Merge branch 'zip64-fix'
Notably fix ZIP64 creation with individual files larger than 4GB. See https://github.com/wxWidgets/wxWidgets/pull/730
This commit is contained in:
@@ -110,6 +110,14 @@ enum wxZipFlags
|
|||||||
wxZIP_RESERVED = 0xF000
|
wxZIP_RESERVED = 0xF000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum wxZipArchiveFormat
|
||||||
|
{
|
||||||
|
/// Default zip format
|
||||||
|
wxZIP_FORMAT_DEFAULT,
|
||||||
|
/// ZIP64 format
|
||||||
|
wxZIP_FORMAT_ZIP64
|
||||||
|
};
|
||||||
|
|
||||||
// Forward decls
|
// Forward decls
|
||||||
//
|
//
|
||||||
class WXDLLIMPEXP_FWD_BASE wxZipEntry;
|
class WXDLLIMPEXP_FWD_BASE wxZipEntry;
|
||||||
@@ -131,6 +139,8 @@ public:
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Zip Entry - holds the meta data for a file in the zip
|
// Zip Entry - holds the meta data for a file in the zip
|
||||||
|
|
||||||
|
class wxDataOutputStream;
|
||||||
|
|
||||||
class WXDLLIMPEXP_BASE wxZipEntry : public wxArchiveEntry
|
class WXDLLIMPEXP_BASE wxZipEntry : public wxArchiveEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -225,7 +235,7 @@ private:
|
|||||||
wxArchiveEntry* DoClone() const wxOVERRIDE { return ZipClone(); }
|
wxArchiveEntry* DoClone() const wxOVERRIDE { return ZipClone(); }
|
||||||
|
|
||||||
size_t ReadLocal(wxInputStream& stream, wxMBConv& conv);
|
size_t ReadLocal(wxInputStream& stream, wxMBConv& conv);
|
||||||
size_t WriteLocal(wxOutputStream& stream, wxMBConv& conv) const;
|
size_t WriteLocal(wxOutputStream& stream, wxMBConv& conv, wxZipArchiveFormat zipFormat);
|
||||||
|
|
||||||
size_t ReadCentral(wxInputStream& stream, wxMBConv& conv);
|
size_t ReadCentral(wxInputStream& stream, wxMBConv& conv);
|
||||||
size_t WriteCentral(wxOutputStream& stream, wxMBConv& conv) const;
|
size_t WriteCentral(wxOutputStream& stream, wxMBConv& conv) const;
|
||||||
@@ -234,6 +244,9 @@ private:
|
|||||||
size_t WriteDescriptor(wxOutputStream& stream, wxUint32 crc,
|
size_t WriteDescriptor(wxOutputStream& stream, wxUint32 crc,
|
||||||
wxFileOffset compressedSize, wxFileOffset size);
|
wxFileOffset compressedSize, wxFileOffset size);
|
||||||
|
|
||||||
|
void WriteLocalFileSizes(wxDataOutputStream& ds) const;
|
||||||
|
void WriteLocalZip64ExtraInfo(wxOutputStream& stream) const;
|
||||||
|
|
||||||
bool LoadExtraInfo(const char* extraData, wxUint16 extraLen, bool localInfo);
|
bool LoadExtraInfo(const char* extraData, wxUint16 extraLen, bool localInfo);
|
||||||
|
|
||||||
wxUint16 GetInternalFlags(bool checkForUTF8) const;
|
wxUint16 GetInternalFlags(bool checkForUTF8) const;
|
||||||
@@ -256,6 +269,7 @@ private:
|
|||||||
wxUint16 m_DiskStart; // for multidisk archives, not unsupported
|
wxUint16 m_DiskStart; // for multidisk archives, not unsupported
|
||||||
wxUint16 m_InternalAttributes; // bit 0 set for text files
|
wxUint16 m_InternalAttributes; // bit 0 set for text files
|
||||||
wxUint32 m_ExternalAttributes; // system specific depends on SystemMadeBy
|
wxUint32 m_ExternalAttributes; // system specific depends on SystemMadeBy
|
||||||
|
wxUint16 m_z64infoOffset; // Offset of ZIP64 local extra data for file sizes
|
||||||
|
|
||||||
class wxZipMemory *m_Extra;
|
class wxZipMemory *m_Extra;
|
||||||
class wxZipMemory *m_LocalExtra;
|
class wxZipMemory *m_LocalExtra;
|
||||||
@@ -307,6 +321,9 @@ public:
|
|||||||
int GetLevel() const { return m_level; }
|
int GetLevel() const { return m_level; }
|
||||||
void WXZIPFIX SetLevel(int level);
|
void WXZIPFIX SetLevel(int level);
|
||||||
|
|
||||||
|
void SetFormat(wxZipArchiveFormat format) { m_format = format; };
|
||||||
|
wxZipArchiveFormat GetFormat() const { return m_format; };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual size_t WXZIPFIX OnSysWrite(const void *buffer, size_t size) wxOVERRIDE;
|
virtual size_t WXZIPFIX OnSysWrite(const void *buffer, size_t size) wxOVERRIDE;
|
||||||
virtual wxFileOffset OnSysTell() const wxOVERRIDE { return m_entrySize; }
|
virtual wxFileOffset OnSysTell() const wxOVERRIDE { return m_entrySize; }
|
||||||
@@ -351,6 +368,7 @@ private:
|
|||||||
wxFileOffset m_offsetAdjustment;
|
wxFileOffset m_offsetAdjustment;
|
||||||
wxString m_Comment;
|
wxString m_Comment;
|
||||||
bool m_endrecWritten;
|
bool m_endrecWritten;
|
||||||
|
wxZipArchiveFormat m_format;
|
||||||
|
|
||||||
wxDECLARE_NO_COPY_CLASS(wxZipOutputStream);
|
wxDECLARE_NO_COPY_CLASS(wxZipOutputStream);
|
||||||
};
|
};
|
||||||
|
@@ -80,6 +80,19 @@ enum wxZipFlags
|
|||||||
wxZIP_RESERVED = 0xF000
|
wxZIP_RESERVED = 0xF000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Zip archive format
|
||||||
|
|
||||||
|
@since 3.1.1
|
||||||
|
*/
|
||||||
|
enum wxZipArchiveFormat
|
||||||
|
{
|
||||||
|
/// Default zip format: use ZIP64 if it is determined to be necessary.
|
||||||
|
wxZIP_FORMAT_DEFAULT,
|
||||||
|
/// ZIP64 format: force the use of ZIP64 format.
|
||||||
|
wxZIP_FORMAT_ZIP64
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@class wxZipNotifier
|
@class wxZipNotifier
|
||||||
@@ -558,11 +571,17 @@ public:
|
|||||||
//@{
|
//@{
|
||||||
/**
|
/**
|
||||||
Takes ownership of @a entry and uses it to create a new entry in the zip.
|
Takes ownership of @a entry and uses it to create a new entry in the zip.
|
||||||
|
|
||||||
|
If you do not specify a size and plan to put more than 4GB data into the
|
||||||
|
entry see SetFormat()
|
||||||
*/
|
*/
|
||||||
bool PutNextEntry(wxZipEntry* entry);
|
bool PutNextEntry(wxZipEntry* entry);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create a new entry with the given name, timestamp and size.
|
Create a new entry with the given name, timestamp and size.
|
||||||
|
|
||||||
|
If you do not specify a size and plan to put more than 4GB data into the
|
||||||
|
entry see SetFormat()
|
||||||
*/
|
*/
|
||||||
bool PutNextEntry(const wxString& name,
|
bool PutNextEntry(const wxString& name,
|
||||||
const wxDateTime& dt = wxDateTime::Now(),
|
const wxDateTime& dt = wxDateTime::Now(),
|
||||||
@@ -574,5 +593,33 @@ public:
|
|||||||
It is written at the end of the zip.
|
It is written at the end of the zip.
|
||||||
*/
|
*/
|
||||||
void SetComment(const wxString& comment);
|
void SetComment(const wxString& comment);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the format of the archive.
|
||||||
|
|
||||||
|
The normal zip format is limited to single files and the complete
|
||||||
|
archive smaller than 4GB with less then 65k files. If any of these
|
||||||
|
limits are exceeded, this class will automatically create a ZIP64 file,
|
||||||
|
so in most situations calling SetFormat() is not necessary.
|
||||||
|
|
||||||
|
However to support single entries with more than 4GB of data
|
||||||
|
(compressed or original) whose sizes are unknown when adding the
|
||||||
|
entry with PutNextEntry(), the format has to be set to
|
||||||
|
wxZIP_FORMAT_ZIP64 before adding such entries.
|
||||||
|
|
||||||
|
@since 3.1.1
|
||||||
|
*/
|
||||||
|
void SetFormat(wxZipArchiveFormat format);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the format of the archive.
|
||||||
|
|
||||||
|
This returns the value passed to SetFormat() and not necessarily the
|
||||||
|
actual archive format (e.g. this method could return
|
||||||
|
wxZIP_FORMAT_DEFAULT even if a ZIP64 will end up being created).
|
||||||
|
|
||||||
|
@since 3.1.1
|
||||||
|
|
||||||
|
wxZipArchiveFormat GetFormat() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -133,7 +133,7 @@ static inline wxUint64 CrackUint64(const char *m)
|
|||||||
(static_cast<wxUint64>(n[6]) << 48) |
|
(static_cast<wxUint64>(n[6]) << 48) |
|
||||||
(static_cast<wxUint64>(n[5]) << 40) |
|
(static_cast<wxUint64>(n[5]) << 40) |
|
||||||
(static_cast<wxUint64>(n[4]) << 32) |
|
(static_cast<wxUint64>(n[4]) << 32) |
|
||||||
(n[3] << 24) | (n[2] << 16) | (n[1] << 8) | n[0];
|
(static_cast<wxUint64>(n[3]) << 24) | (n[2] << 16) | (n[1] << 8) | n[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode a little endian wxUint32 number from a character array
|
// Decode a little endian wxUint32 number from a character array
|
||||||
@@ -757,6 +757,7 @@ wxZipEntry::wxZipEntry(
|
|||||||
m_DiskStart(0),
|
m_DiskStart(0),
|
||||||
m_InternalAttributes(0),
|
m_InternalAttributes(0),
|
||||||
m_ExternalAttributes(0),
|
m_ExternalAttributes(0),
|
||||||
|
m_z64infoOffset(0),
|
||||||
m_Extra(NULL),
|
m_Extra(NULL),
|
||||||
m_LocalExtra(NULL),
|
m_LocalExtra(NULL),
|
||||||
m_zipnotifier(NULL),
|
m_zipnotifier(NULL),
|
||||||
@@ -792,6 +793,7 @@ wxZipEntry::wxZipEntry(const wxZipEntry& e)
|
|||||||
m_DiskStart(e.m_DiskStart),
|
m_DiskStart(e.m_DiskStart),
|
||||||
m_InternalAttributes(e.m_InternalAttributes),
|
m_InternalAttributes(e.m_InternalAttributes),
|
||||||
m_ExternalAttributes(e.m_ExternalAttributes),
|
m_ExternalAttributes(e.m_ExternalAttributes),
|
||||||
|
m_z64infoOffset(0),
|
||||||
m_Extra(AddRef(e.m_Extra)),
|
m_Extra(AddRef(e.m_Extra)),
|
||||||
m_LocalExtra(AddRef(e.m_LocalExtra)),
|
m_LocalExtra(AddRef(e.m_LocalExtra)),
|
||||||
m_zipnotifier(NULL),
|
m_zipnotifier(NULL),
|
||||||
@@ -1127,7 +1129,7 @@ size_t wxZipEntry::ReadLocal(wxInputStream& stream, wxMBConv& conv)
|
|||||||
return LOCAL_SIZE + nameLen + extraLen;
|
return LOCAL_SIZE + nameLen + extraLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t wxZipEntry::WriteLocal(wxOutputStream& stream, wxMBConv& conv) const
|
size_t wxZipEntry::WriteLocal(wxOutputStream& stream, wxMBConv& conv, wxZipArchiveFormat zipFormat)
|
||||||
{
|
{
|
||||||
wxString unixName = GetName(wxPATH_UNIX);
|
wxString unixName = GetName(wxPATH_UNIX);
|
||||||
const wxWX2MBbuf name_buf = unixName.mb_str(conv);
|
const wxWX2MBbuf name_buf = unixName.mb_str(conv);
|
||||||
@@ -1135,9 +1137,11 @@ size_t wxZipEntry::WriteLocal(wxOutputStream& stream, wxMBConv& conv) const
|
|||||||
if (!name) name = "";
|
if (!name) name = "";
|
||||||
wxUint16 nameLen = wx_truncate_cast(wxUint16, strlen(name));
|
wxUint16 nameLen = wx_truncate_cast(wxUint16, strlen(name));
|
||||||
|
|
||||||
bool z64Required = m_CompressedSize > 0xffffffff || m_Size > 0xffffffff;
|
if ( (zipFormat == wxZIP_FORMAT_ZIP64) ||
|
||||||
|
m_CompressedSize >= 0xffffffff || m_Size >= 0xffffffff )
|
||||||
|
m_z64infoOffset = LOCAL_SIZE + nameLen;
|
||||||
wxUint16 versionNeeded =
|
wxUint16 versionNeeded =
|
||||||
z64Required ? Z64_VERSION_NEEDED_TO_EXTRACT : int(m_VersionNeeded);
|
(m_z64infoOffset > 0) ? Z64_VERSION_NEEDED_TO_EXTRACT : int(m_VersionNeeded);
|
||||||
|
|
||||||
wxDataOutputStream ds(stream);
|
wxDataOutputStream ds(stream);
|
||||||
|
|
||||||
@@ -1145,25 +1149,17 @@ size_t wxZipEntry::WriteLocal(wxOutputStream& stream, wxMBConv& conv) const
|
|||||||
ds.Write32(GetDateTime().GetAsDOS());
|
ds.Write32(GetDateTime().GetAsDOS());
|
||||||
|
|
||||||
ds.Write32(m_Crc);
|
ds.Write32(m_Crc);
|
||||||
ds.Write32(m_CompressedSize != wxInvalidOffset ?
|
WriteLocalFileSizes(ds);
|
||||||
LimitUint32(m_CompressedSize) : 0);
|
|
||||||
ds.Write32(m_Size != wxInvalidOffset ?
|
|
||||||
LimitUint32(m_Size) : 0);
|
|
||||||
|
|
||||||
ds << nameLen;
|
ds << nameLen;
|
||||||
wxUint16 extraLen = wx_truncate_cast(wxUint16, GetLocalExtraLen());
|
wxUint16 extraLen = wx_truncate_cast(wxUint16, GetLocalExtraLen());
|
||||||
if (z64Required)
|
if (m_z64infoOffset)
|
||||||
extraLen += 20; // tag and 2x64bit file sizes
|
extraLen += 20; // tag and 2x64bit file sizes
|
||||||
ds.Write16(extraLen);
|
ds.Write16(extraLen);
|
||||||
|
|
||||||
stream.Write(name, nameLen);
|
stream.Write(name, nameLen);
|
||||||
if (z64Required)
|
if (m_z64infoOffset > 0)
|
||||||
{
|
WriteLocalZip64ExtraInfo(stream);
|
||||||
ds.Write16(1); // id
|
|
||||||
ds.Write16(16); // record size
|
|
||||||
ds.Write64(static_cast<wxInt64>(m_CompressedSize));
|
|
||||||
ds.Write64(static_cast<wxInt64>(m_Size));
|
|
||||||
}
|
|
||||||
if (GetLocalExtraLen())
|
if (GetLocalExtraLen())
|
||||||
stream.Write(m_LocalExtra->GetData(), GetLocalExtraLen());
|
stream.Write(m_LocalExtra->GetData(), GetLocalExtraLen());
|
||||||
|
|
||||||
@@ -1264,7 +1260,7 @@ size_t wxZipEntry::WriteCentral(wxOutputStream& stream, wxMBConv& conv) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
wxUint16 versionNeeded =
|
wxUint16 versionNeeded =
|
||||||
(z64Required) ? Z64_VERSION_NEEDED_TO_EXTRACT : GetVersionNeeded();
|
(z64Required || m_z64infoOffset) ? Z64_VERSION_NEEDED_TO_EXTRACT : GetVersionNeeded();
|
||||||
|
|
||||||
wxDataOutputStream ds(stream);
|
wxDataOutputStream ds(stream);
|
||||||
|
|
||||||
@@ -1288,10 +1284,10 @@ size_t wxZipEntry::WriteCentral(wxOutputStream& stream, wxMBConv& conv) const
|
|||||||
{
|
{
|
||||||
ds.Write16(1); // tag
|
ds.Write16(1); // tag
|
||||||
ds.Write16(z64InfoLen); // record size
|
ds.Write16(z64InfoLen); // record size
|
||||||
if (m_CompressedSize > 0xffffffff)
|
|
||||||
ds.Write64(static_cast<wxInt64>(m_CompressedSize));
|
|
||||||
if (m_Size > 0xffffffff)
|
if (m_Size > 0xffffffff)
|
||||||
ds.Write64(static_cast<wxInt64>(m_Size));
|
ds.Write64(static_cast<wxInt64>(m_Size));
|
||||||
|
if (m_CompressedSize > 0xffffffff)
|
||||||
|
ds.Write64(static_cast<wxInt64>(m_CompressedSize));
|
||||||
if (m_Offset > 0xffffffff)
|
if (m_Offset > 0xffffffff)
|
||||||
ds.Write64(static_cast<wxInt64>(m_Offset));
|
ds.Write64(static_cast<wxInt64>(m_Offset));
|
||||||
}
|
}
|
||||||
@@ -1357,12 +1353,40 @@ size_t wxZipEntry::WriteDescriptor(wxOutputStream& stream, wxUint32 crc,
|
|||||||
wxDataOutputStream ds(stream);
|
wxDataOutputStream ds(stream);
|
||||||
|
|
||||||
ds.Write32(crc);
|
ds.Write32(crc);
|
||||||
ds.Write32(wx_truncate_cast(wxUint32, compressedSize));
|
WriteLocalFileSizes(ds);
|
||||||
ds.Write32(wx_truncate_cast(wxUint32, size));
|
|
||||||
|
|
||||||
return SUMS_SIZE;
|
return SUMS_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxZipEntry::WriteLocalFileSizes(wxDataOutputStream& ds) const
|
||||||
|
{
|
||||||
|
wxUint32 compressedSize;
|
||||||
|
wxUint32 size;
|
||||||
|
if (m_z64infoOffset > 0)
|
||||||
|
{
|
||||||
|
compressedSize = 0xffffffff;
|
||||||
|
size = 0xffffffff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
compressedSize = m_CompressedSize != wxInvalidOffset ?
|
||||||
|
wx_truncate_cast(wxUint32, m_CompressedSize) : 0;
|
||||||
|
size = m_Size != wxInvalidOffset ?
|
||||||
|
wx_truncate_cast(wxUint32, m_Size) : 0;
|
||||||
|
}
|
||||||
|
ds.Write32(compressedSize);
|
||||||
|
ds.Write32(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxZipEntry::WriteLocalZip64ExtraInfo(wxOutputStream& stream) const
|
||||||
|
{
|
||||||
|
wxDataOutputStream ds(stream);
|
||||||
|
ds.Write16(1); // id
|
||||||
|
ds.Write16(16); // record size
|
||||||
|
ds.Write64(static_cast<wxUint64>(m_Size));
|
||||||
|
ds.Write64(static_cast<wxUint64>(m_CompressedSize));
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the flags as specified or including the UTF-8 flag if filename
|
// Returns the flags as specified or including the UTF-8 flag if filename
|
||||||
// contains non ASCII characters
|
// contains non ASCII characters
|
||||||
wxUint16 wxZipEntry::GetInternalFlags(bool checkForUTF8) const
|
wxUint16 wxZipEntry::GetInternalFlags(bool checkForUTF8) const
|
||||||
@@ -2173,6 +2197,7 @@ void wxZipOutputStream::Init(int level)
|
|||||||
m_level = level;
|
m_level = level;
|
||||||
m_offsetAdjustment = wxInvalidOffset;
|
m_offsetAdjustment = wxInvalidOffset;
|
||||||
m_endrecWritten = false;
|
m_endrecWritten = false;
|
||||||
|
m_format = wxZIP_FORMAT_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxZipOutputStream::~wxZipOutputStream()
|
wxZipOutputStream::~wxZipOutputStream()
|
||||||
@@ -2401,7 +2426,7 @@ void wxZipOutputStream::CreatePendingEntry(const void *buffer, size_t size)
|
|||||||
if (spPending->m_CompressedSize != wxInvalidOffset)
|
if (spPending->m_CompressedSize != wxInvalidOffset)
|
||||||
spPending->m_Flags |= wxZIP_SUMS_FOLLOW;
|
spPending->m_Flags |= wxZIP_SUMS_FOLLOW;
|
||||||
|
|
||||||
m_headerSize = spPending->WriteLocal(*m_parent_o_stream, GetConv());
|
m_headerSize = spPending->WriteLocal(*m_parent_o_stream, GetConv(), m_format);
|
||||||
m_lasterror = m_parent_o_stream->GetLastError();
|
m_lasterror = m_parent_o_stream->GetLastError();
|
||||||
|
|
||||||
if (IsOk()) {
|
if (IsOk()) {
|
||||||
@@ -2454,7 +2479,7 @@ void wxZipOutputStream::CreatePendingEntry()
|
|||||||
}
|
}
|
||||||
|
|
||||||
spPending->m_Flags &= ~wxZIP_SUMS_FOLLOW;
|
spPending->m_Flags &= ~wxZIP_SUMS_FOLLOW;
|
||||||
m_headerSize = spPending->WriteLocal(*m_parent_o_stream, GetConv());
|
m_headerSize = spPending->WriteLocal(*m_parent_o_stream, GetConv(), m_format);
|
||||||
|
|
||||||
if (m_parent_o_stream->IsOk()) {
|
if (m_parent_o_stream->IsOk()) {
|
||||||
m_entries.push_back(spPending.release());
|
m_entries.push_back(spPending.release());
|
||||||
@@ -2552,6 +2577,12 @@ bool wxZipOutputStream::CloseEntry()
|
|||||||
m_parent_o_stream->SeekO(headerOffset + SUMS_OFFSET);
|
m_parent_o_stream->SeekO(headerOffset + SUMS_OFFSET);
|
||||||
entry.WriteDescriptor(*m_parent_o_stream, m_crcAccumulator,
|
entry.WriteDescriptor(*m_parent_o_stream, m_crcAccumulator,
|
||||||
compressedSize, m_entrySize);
|
compressedSize, m_entrySize);
|
||||||
|
if (entry.m_z64infoOffset > 0)
|
||||||
|
{
|
||||||
|
// Skip to ZIP64 extended information extra field
|
||||||
|
m_parent_o_stream->SeekO(headerOffset + entry.m_z64infoOffset);
|
||||||
|
entry.WriteLocalZip64ExtraInfo(*m_parent_o_stream);
|
||||||
|
}
|
||||||
m_parent_o_stream->SeekO(here);
|
m_parent_o_stream->SeekO(here);
|
||||||
m_lasterror = m_parent_o_stream->GetLastError();
|
m_lasterror = m_parent_o_stream->GetLastError();
|
||||||
} else {
|
} else {
|
||||||
@@ -2565,7 +2596,14 @@ bool wxZipOutputStream::CloseEntry()
|
|||||||
m_store->Close();
|
m_store->Close();
|
||||||
m_raw = false;
|
m_raw = false;
|
||||||
|
|
||||||
if (IsOk())
|
if (IsOk() && entry.m_z64infoOffset == 0 &&
|
||||||
|
(entry.m_CompressedSize > 0xffffffff || entry.m_Size > 0xffffffff))
|
||||||
|
{
|
||||||
|
wxLogError(_("error writing zip entry '%s': file too large without ZIP64"),
|
||||||
|
entry.GetName().c_str());
|
||||||
|
m_lasterror = wxSTREAM_WRITE_ERROR;
|
||||||
|
}
|
||||||
|
else if (IsOk())
|
||||||
m_lasterror = m_parent_o_stream->GetLastError();
|
m_lasterror = m_parent_o_stream->GetLastError();
|
||||||
else
|
else
|
||||||
wxLogError(_("error writing zip entry '%s': bad crc or length"),
|
wxLogError(_("error writing zip entry '%s': bad crc or length"),
|
||||||
|
Reference in New Issue
Block a user