Coverage Report

Created: 2026-09-20 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wxwidgets/include/wx/tarstrm.h
Line
Count
Source
1
/////////////////////////////////////////////////////////////////////////////
2
// Name:        wx/tarstrm.h
3
// Purpose:     Streams for Tar files
4
// Author:      Mike Wetherell
5
// Copyright:   (c) 2004 Mike Wetherell
6
// Licence:     wxWindows licence
7
/////////////////////////////////////////////////////////////////////////////
8
9
#ifndef _WX_WXTARSTREAM_H__
10
#define _WX_WXTARSTREAM_H__
11
12
#include "wx/defs.h"
13
14
#if wxUSE_TARSTREAM
15
16
#include "wx/archive.h"
17
18
#include <unordered_map>
19
20
/////////////////////////////////////////////////////////////////////////////
21
// Constants
22
23
// TypeFlag values
24
enum wxTarType
25
{
26
    wxTAR_REGTYPE   = '0',      // regular file
27
    wxTAR_LNKTYPE   = '1',      // hard link
28
    wxTAR_SYMTYPE   = '2',      // symbolic link
29
    wxTAR_CHRTYPE   = '3',      // character special
30
    wxTAR_BLKTYPE   = '4',      // block special
31
    wxTAR_DIRTYPE   = '5',      // directory
32
    wxTAR_FIFOTYPE  = '6',      // named pipe
33
    wxTAR_CONTTYPE  = '7'       // contiguous file
34
};
35
36
// Archive Formats (use wxTAR_PAX, it's backward compatible)
37
enum wxTarFormat
38
{
39
    wxTAR_USTAR,                // POSIX.1-1990 tar format
40
    wxTAR_PAX                   // POSIX.1-2001 tar format
41
};
42
43
44
/////////////////////////////////////////////////////////////////////////////
45
// wxTarNotifier
46
47
class WXDLLIMPEXP_BASE wxTarNotifier
48
{
49
public:
50
    virtual ~wxTarNotifier() = default;
51
52
    virtual void OnEntryUpdated(class wxTarEntry& entry) = 0;
53
};
54
55
56
/////////////////////////////////////////////////////////////////////////////
57
// Tar Entry - hold the meta data for a file in the tar
58
59
class WXDLLIMPEXP_BASE wxTarEntry : public wxArchiveEntry
60
{
61
public:
62
    wxTarEntry(const wxString& name = wxEmptyString,
63
               const wxDateTime& dt = wxDateTime::Now(),
64
               wxFileOffset size = wxInvalidOffset);
65
    virtual ~wxTarEntry();
66
67
    wxTarEntry(const wxTarEntry& entry);
68
    wxTarEntry& operator=(const wxTarEntry& entry);
69
70
    // Get accessors
71
    wxString     GetName(wxPathFormat format = wxPATH_NATIVE) const override;
72
0
    wxString     GetInternalName() const override        { return m_Name; }
73
0
    wxPathFormat GetInternalFormat() const override      { return wxPATH_UNIX; }
74
    int          GetMode() const;
75
0
    int          GetUserId() const              { return m_UserId; }
76
0
    int          GetGroupId() const             { return m_GroupId; }
77
8.74k
    wxFileOffset GetSize() const override                { return m_Size; }
78
6.31k
    wxFileOffset GetOffset() const override              { return m_Offset; }
79
0
    wxDateTime   GetDateTime() const override            { return m_ModifyTime; }
80
0
    wxDateTime   GetAccessTime() const          { return m_AccessTime; }
81
0
    wxDateTime   GetCreateTime() const          { return m_CreateTime; }
82
12.1k
    int          GetTypeFlag() const            { return m_TypeFlag; }
83
0
    wxString     GetLinkName() const            { return m_LinkName; }
84
0
    wxString     GetUserName() const            { return m_UserName; }
85
0
    wxString     GetGroupName() const           { return m_GroupName; }
86
0
    int          GetDevMajor() const            { return m_DevMajor; }
87
0
    int          GetDevMinor() const            { return m_DevMinor; }
88
89
    // is accessors
90
    bool IsDir() const override;
91
0
    bool IsReadOnly() const override                     { return !(m_Mode & 0222); }
92
93
    // set accessors
94
    void SetName(const wxString& name, wxPathFormat format = wxPATH_NATIVE) override;
95
6.31k
    void SetUserId(int id)                      { m_UserId = id; }
96
6.31k
    void SetGroupId(int id)                     { m_GroupId = id; }
97
    void SetMode(int mode);
98
6.31k
    void SetSize(wxFileOffset size) override             { m_Size = size; }
99
6.31k
    void SetDateTime(const wxDateTime& dt) override      { m_ModifyTime = dt; }
100
6.31k
    void SetAccessTime(const wxDateTime& dt)    { m_AccessTime = dt; }
101
6.31k
    void SetCreateTime(const wxDateTime& dt)    { m_CreateTime = dt; }
102
6.31k
    void SetTypeFlag(int type)                  { m_TypeFlag = type; }
103
6.31k
    void SetLinkName(const wxString& link)      { m_LinkName = link; }
104
3.51k
    void SetUserName(const wxString& user)      { m_UserName = user; }
105
3.51k
    void SetGroupName(const wxString& group)    { m_GroupName = group; }
106
3.51k
    void SetDevMajor(int dev)                   { m_DevMajor = dev; }
107
3.51k
    void SetDevMinor(int dev)                   { m_DevMinor = dev; }
108
109
    // set is accessors
110
    void SetIsDir(bool isDir = true) override;
111
    void SetIsReadOnly(bool isReadOnly = true) override;
112
113
    static wxString GetInternalName(const wxString& name,
114
                                    wxPathFormat format = wxPATH_NATIVE,
115
                                    bool *pIsDir = nullptr);
116
117
0
    wxNODISCARD wxTarEntry *Clone() const { return new wxTarEntry(*this); }
118
119
0
    void SetNotifier(wxTarNotifier& WXUNUSED(notifier)) { }
120
121
private:
122
6.31k
    void SetOffset(wxFileOffset offset) override         { m_Offset = offset; }
123
124
0
    virtual wxArchiveEntry* DoClone() const override     { return Clone(); }
125
126
    wxString     m_Name;
127
    int          m_Mode;
128
    bool         m_IsModeSet;
129
    int          m_UserId;
130
    int          m_GroupId;
131
    wxFileOffset m_Size;
132
    wxFileOffset m_Offset;
133
    wxDateTime   m_ModifyTime;
134
    wxDateTime   m_AccessTime;
135
    wxDateTime   m_CreateTime;
136
    int          m_TypeFlag;
137
    wxString     m_LinkName;
138
    wxString     m_UserName;
139
    wxString     m_GroupName;
140
    int          m_DevMajor;
141
    int          m_DevMinor;
142
143
    friend class wxTarInputStream;
144
145
    wxDECLARE_DYNAMIC_CLASS(wxTarEntry);
146
};
147
148
149
/////////////////////////////////////////////////////////////////////////////
150
// wxTarInputStream
151
152
class WXDLLIMPEXP_BASE wxTarInputStream : public wxArchiveInputStream
153
{
154
public:
155
    typedef wxTarEntry entry_type;
156
157
    wxTarInputStream(wxInputStream& stream, wxMBConv& conv = wxConvLocal);
158
    wxTarInputStream(wxInputStream *stream, wxMBConv& conv = wxConvLocal);
159
    virtual ~wxTarInputStream();
160
161
    bool OpenEntry(wxTarEntry& entry);
162
    bool CloseEntry() override;
163
164
    wxTarEntry *GetNextEntry();
165
166
0
    wxFileOffset GetLength() const override      { return m_size; }
167
0
    bool IsSeekable() const override { return m_parent_i_stream->IsSeekable(); }
168
169
    // Limit on the extended header size, to avoid excessive allocation.
170
2.57k
    static size_t GetMaxExtendedHeaderSize() { return sm_maxExtendedHeaderSize; }
171
0
    static void SetMaxExtendedHeaderSize(size_t size) { sm_maxExtendedHeaderSize = size; }
172
173
protected:
174
    size_t OnSysRead(void *buffer, size_t size) override;
175
0
    wxFileOffset OnSysTell() const override      { return m_pos; }
176
    wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode) override;
177
178
private:
179
    using wxTarHeaderRecords = std::unordered_map<wxString, wxString>;
180
181
    void Init();
182
183
0
    wxArchiveEntry *DoGetNextEntry() override    { return GetNextEntry(); }
184
    bool OpenEntry(wxArchiveEntry& entry) override;
185
19.6k
    bool IsOpened() const               { return m_pos != wxInvalidOffset; }
186
187
    wxStreamError ReadHeaders();
188
    bool ReadExtendedHeader(wxTarHeaderRecords*& recs);
189
190
    wxString GetExtendedHeader(const wxString& key) const;
191
    wxString GetHeaderPath() const;
192
    wxFileOffset GetHeaderNumber(int id) const;
193
    wxString GetHeaderString(int id) const;
194
    wxDateTime GetHeaderDate(const wxString& key) const;
195
196
    wxFileOffset m_pos;     // position within the current entry
197
    wxFileOffset m_offset;  // offset to the start of the entry's data
198
    wxFileOffset m_size;    // size of the current entry's data
199
200
    int m_sumType;
201
    int m_tarType;
202
    class wxTarHeaderBlock *m_hdr;
203
    wxTarHeaderRecords *m_HeaderRecs;
204
    wxTarHeaderRecords *m_GlobalHeaderRecs;
205
206
    static size_t sm_maxExtendedHeaderSize;
207
208
    wxDECLARE_NO_COPY_CLASS(wxTarInputStream);
209
};
210
211
212
/////////////////////////////////////////////////////////////////////////////
213
// wxTarOutputStream
214
215
class WXDLLIMPEXP_BASE wxTarOutputStream : public wxArchiveOutputStream
216
{
217
public:
218
    wxTarOutputStream(wxOutputStream& stream,
219
                      wxTarFormat format = wxTAR_PAX,
220
                      wxMBConv& conv = wxConvLocal);
221
    wxTarOutputStream(wxOutputStream *stream,
222
                      wxTarFormat format = wxTAR_PAX,
223
                      wxMBConv& conv = wxConvLocal);
224
    virtual ~wxTarOutputStream();
225
226
    bool PutNextEntry(wxTarEntry *entry);
227
228
    bool PutNextEntry(const wxString& name,
229
                      const wxDateTime& dt = wxDateTime::Now(),
230
                      wxFileOffset size = wxInvalidOffset) override;
231
232
    bool PutNextDirEntry(const wxString& name,
233
                         const wxDateTime& dt = wxDateTime::Now()) override;
234
235
    bool CopyEntry(wxTarEntry *entry, wxTarInputStream& inputStream);
236
0
    bool CopyArchiveMetaData(wxTarInputStream& WXUNUSED(s)) { return true; }
237
238
    void Sync() override;
239
    bool CloseEntry() override;
240
    bool Close() override;
241
242
0
    bool IsSeekable() const override { return m_parent_o_stream->IsSeekable(); }
243
244
0
    void SetBlockingFactor(int factor)  { m_BlockingFactor = factor; }
245
0
    int GetBlockingFactor() const       { return m_BlockingFactor; }
246
247
protected:
248
    size_t OnSysWrite(const void *buffer, size_t size) override;
249
0
    wxFileOffset OnSysTell() const override      { return m_pos; }
250
    wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode) override;
251
252
private:
253
    void Init(wxTarFormat format);
254
255
    bool PutNextEntry(wxArchiveEntry *entry) override;
256
    bool CopyEntry(wxArchiveEntry *entry, wxArchiveInputStream& stream) override;
257
0
    bool CopyArchiveMetaData(wxArchiveInputStream& WXUNUSED(s)) override { return true; }
258
0
    bool IsOpened() const               { return m_pos != wxInvalidOffset; }
259
260
    bool WriteHeaders(wxTarEntry& entry);
261
    bool ModifyHeader();
262
    wxString PaxHeaderPath(const wxString& format, const wxString& path);
263
264
    void SetExtendedHeader(const wxString& key, const wxString& value);
265
    void SetHeaderPath(const wxString& name);
266
    bool SetHeaderNumber(int id, wxFileOffset n);
267
    void SetHeaderString(int id, const wxString& str);
268
    void SetHeaderDate(const wxString& key, const wxDateTime& datetime);
269
270
    wxFileOffset m_pos;     // position within the current entry
271
    wxFileOffset m_maxpos;  // max pos written
272
    wxFileOffset m_size;    // expected entry size
273
274
    wxFileOffset m_headpos; // offset within the file to the entry's header
275
    wxFileOffset m_datapos; // offset within the file to the entry's data
276
277
    wxFileOffset m_tarstart;// offset within the file to the tar
278
    wxFileOffset m_tarsize; // size of tar so far
279
280
    bool m_pax;
281
    int m_BlockingFactor;
282
    wxUint32 m_chksum;
283
    bool m_large;
284
    class wxTarHeaderBlock *m_hdr;
285
    class wxTarHeaderBlock *m_hdr2;
286
    char *m_extendedHdr;
287
    size_t m_extendedSize;
288
    wxString m_badfit;
289
    bool m_endrecWritten;
290
291
    wxDECLARE_NO_COPY_CLASS(wxTarOutputStream);
292
};
293
294
295
/////////////////////////////////////////////////////////////////////////////
296
// Iterators
297
298
typedef wxArchiveIterator<wxTarInputStream> wxTarIter;
299
typedef wxArchiveIterator<wxTarInputStream,
300
         std::pair<wxString, wxTarEntry*> > wxTarPairIter;
301
302
303
/////////////////////////////////////////////////////////////////////////////
304
// wxTarClassFactory
305
306
class WXDLLIMPEXP_BASE wxTarClassFactory : public wxArchiveClassFactory
307
{
308
public:
309
    typedef wxTarEntry        entry_type;
310
    typedef wxTarInputStream  instream_type;
311
    typedef wxTarOutputStream outstream_type;
312
    typedef wxTarNotifier     notifier_type;
313
    typedef wxTarIter         iter_type;
314
    typedef wxTarPairIter     pairiter_type;
315
316
    wxTarClassFactory();
317
318
    wxTarEntry *NewEntry() const
319
0
        { return new wxTarEntry; }
320
    wxTarInputStream *NewStream(wxInputStream& stream) const
321
0
        { return new wxTarInputStream(stream, GetConv()); }
322
    wxTarOutputStream *NewStream(wxOutputStream& stream) const
323
0
        { return new wxTarOutputStream(stream, wxTAR_PAX, GetConv()); }
324
    wxTarInputStream *NewStream(wxInputStream *stream) const
325
0
        { return new wxTarInputStream(stream, GetConv()); }
326
    wxTarOutputStream *NewStream(wxOutputStream *stream) const
327
0
        { return new wxTarOutputStream(stream, wxTAR_PAX, GetConv()); }
328
329
    wxString GetInternalName(const wxString& name,
330
                             wxPathFormat format = wxPATH_NATIVE) const override
331
0
        { return wxTarEntry::GetInternalName(name, format); }
332
333
    const wxChar * const *GetProtocols(wxStreamProtocolType type
334
                                       = wxSTREAM_PROTOCOL) const override;
335
336
protected:
337
    wxArchiveEntry *DoNewEntry() const override
338
0
        { return NewEntry(); }
339
    wxArchiveInputStream *DoNewStream(wxInputStream& stream) const override
340
0
        { return NewStream(stream); }
341
    wxArchiveOutputStream *DoNewStream(wxOutputStream& stream) const override
342
0
        { return NewStream(stream); }
343
    wxArchiveInputStream *DoNewStream(wxInputStream *stream) const override
344
0
        { return NewStream(stream); }
345
    wxArchiveOutputStream *DoNewStream(wxOutputStream *stream) const override
346
0
        { return NewStream(stream); }
347
348
private:
349
    wxDECLARE_DYNAMIC_CLASS(wxTarClassFactory);
350
};
351
352
353
#endif // wxUSE_TARSTREAM
354
355
#endif // _WX_WXTARSTREAM_H__