summaryrefslogtreecommitdiff
path: root/zip/zip.cpp
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@redhat.com>2024-10-31 23:23:54 +0100
committerTomas Bzatek <tbzatek@redhat.com>2024-10-31 23:23:54 +0100
commit5a431384cdec4e3ea2d58577fd7bf7ac1bc607dc (patch)
tree5590c4786514e19398e31b8134aeb7d416e90119 /zip/zip.cpp
parent1e0e627a510785edd1fcd6ae460b8575647d598b (diff)
downloadtuxcmd-modules-5a431384cdec4e3ea2d58577fd7bf7ac1bc607dc.tar.xz
zip: Use Finalize() to safely flush changes to the archiveHEADmaster
Diffstat (limited to 'zip/zip.cpp')
-rw-r--r--zip/zip.cpp65
1 files changed, 54 insertions, 11 deletions
diff --git a/zip/zip.cpp b/zip/zip.cpp
index aefb9f5..fcf2652 100644
--- a/zip/zip.cpp
+++ b/zip/zip.cpp
@@ -171,6 +171,7 @@ struct TVFSGlobs {
struct PathTree *files;
struct VfsFilelistData *vfs_filelist;
+ gboolean in_copy_operation;
TVFSAskQuestionCallback callback_ask_question;
TVFSAskPasswordCallback callback_ask_password;
TVFSProgressCallback callback_progress;
@@ -233,11 +234,12 @@ build_global_filelist (struct TVFSGlobs *globs)
iCount = globs->zip->GetCount ();
/* list files in the archive */
- for (i = 0; i < iCount; i++) {
- fh = globs->zip->GetFileInfo (i);
- if (fh != NULL && _log_level >= LOG_INFO)
- g_print (" [%lu] '%s', IsDir: %i, Size: %" G_GUINT32_FORMAT ", SystemAttr = 0x%" G_GINT32_MODIFIER "X, OriginalAttr = 0x%" G_GINT32_MODIFIER "X, encrypted = %d\n",
- i, (LPCTSTR)fh->GetFileName(), fh->IsDirectory(), fh->m_uUncomprSize, fh->GetSystemAttr(), fh->GetOriginalAttributes(), fh->IsEncrypted());
+ if (_log_level >= LOG_INFO)
+ for (i = 0; i < iCount; i++) {
+ fh = globs->zip->GetFileInfo (i);
+ if (fh != NULL)
+ g_print (" [%lu] '%s', IsDir: %i, Size: %" G_GUINT32_FORMAT ", SystemAttr = 0x%" G_GINT32_MODIFIER "X, OriginalAttr = 0x%" G_GINT32_MODIFIER "X, encrypted = %d\n",
+ i, (LPCTSTR)fh->GetFileName(), fh->IsDirectory(), fh->m_uUncomprSize, fh->GetSystemAttr(), fh->GetOriginalAttributes(), fh->IsEncrypted());
}
for (i = 0; i < iCount; i++) {
@@ -414,6 +416,7 @@ VFSOpenArchive (struct TVFSGlobs *globs, const char *sName, GError **error)
/* set automatic flushing of changes to disk */
globs->zip->SetAutoFinalize (true);
+ globs->zip->SetCommitMode (CZipArchive::CommitMode::cmOnChange);
}
catch (CZipException& e) {
log_error ("VFSOpenArchive: Error while processing archive %s: %s", sName, (LPCTSTR)e.GetErrorDescription());
@@ -444,8 +447,10 @@ VFSClose (struct TVFSGlobs *globs, GError **error)
/* flush and close the archive... */
log_notice ("VFSClose: Closing the archive...");
try {
- if (globs->archive_modified)
+ if (globs->archive_modified) {
globs->zip->FlushBuffers ();
+ globs->zip->Finalize (false);
+ }
/* In case of inconsistency, try using afWriteDir value.
* (use when an exception was thrown, the Close method writes the
* central directory structure to the archive, so that the archive should be usable.)
@@ -615,6 +620,11 @@ VFSMkDir (struct TVFSGlobs *globs, const char *sDirName, GError **error)
try {
try {
+ /* set system compatibility first */
+ if (! globs->zip->SetSystemCompatibility (ZipCompatibility::zcUnix)) {
+ log_warn ("VFSMkDir: Unable to set system compatibility of the ZIP archive to Unix");
+ }
+
header.SetSystemAttr (ZipPlatform::GetDefaultDirAttributes());
s = exclude_leading_path_sep (sDirName);
header.SetFileName (s);
@@ -668,7 +678,7 @@ VFSRemove (struct TVFSGlobs *globs, const char *APath, GError **error)
try {
try {
- if (! globs->zip->RemoveFile (file_no)) {
+ if (! globs->zip->RemoveFile (file_no, true /* bRemoveData */)) {
log_error ("VFSRemove: Delete file '%s' failed.", APath);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Delete file '%s' failed.", APath);
return FALSE;
@@ -827,6 +837,11 @@ VFSChmod (struct TVFSGlobs *globs, const char *FileName, guint32 Mode, GError **
/* write local header information */
globs->zip->OverwriteLocalHeader (file_no);
+ globs->zip->RemoveCentralDirectoryFromArchive ();
+ if (! globs->in_copy_operation) {
+ globs->zip->FlushBuffers ();
+ globs->zip->Finalize (false);
+ }
#if 0
// Re-encrypt the file
@@ -836,8 +851,6 @@ VFSChmod (struct TVFSGlobs *globs, const char *FileName, guint32 Mode, GError **
printf("(EE) VFSChmod: Unable to encrypt the file\n");
}
#endif
- globs->zip->RemoveCentralDirectoryFromArchive ();
- globs->zip->FlushBuffers ();
log_debug ("VFSChmod OK.");
build_global_filelist (globs);
@@ -891,6 +904,11 @@ VFSChangeTimes (struct TVFSGlobs *globs, const char *APath, guint32 mtime, guint
try {
try {
+ /* set system compatibility first */
+ if (! globs->zip->SetSystemCompatibility (ZipCompatibility::zcUnix)) {
+ log_warn ("VFSChangeTimes: Unable to set system compatibility of the ZIP archive to Unix");
+ }
+
/* read the local header information */
globs->zip->ReadLocalHeader (file_no);
header = globs->zip->GetFileInfo (file_no);
@@ -913,6 +931,10 @@ VFSChangeTimes (struct TVFSGlobs *globs, const char *APath, guint32 mtime, guint
/* write local header information */
globs->zip->OverwriteLocalHeader (file_no);
globs->zip->RemoveCentralDirectoryFromArchive ();
+ if (! globs->in_copy_operation) {
+ globs->zip->FlushBuffers ();
+ globs->zip->Finalize (false);
+ }
log_debug ("VFSChangeTimes OK.");
build_global_filelist (globs);
@@ -971,6 +993,7 @@ VFSStartCopyOperation (struct TVFSGlobs *globs, GError **error)
g_return_val_if_fail (globs != NULL, FALSE);
log_debug ("VFSStartCopyOperation: doing nothing for the moment.");
+ globs->in_copy_operation = TRUE;
return TRUE;
}
@@ -980,10 +1003,12 @@ gboolean
VFSStopCopyOperation (struct TVFSGlobs *globs, GError **error)
{
g_return_val_if_fail (globs != NULL, FALSE);
+ globs->in_copy_operation = FALSE;
if (globs->archive_modified) {
log_debug ("VFSStopCopyOperation: archive modified, rebuilding the tree.");
globs->zip->FlushBuffers ();
+ globs->zip->Finalize (false);
build_global_filelist (globs);
} else {
log_debug ("VFSStartCopyOperation: doing nothing for the moment.");
@@ -1118,6 +1143,11 @@ VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDs
try {
do {
try {
+ /* set system compatibility first */
+ if (! globs->zip->SetSystemCompatibility (ZipCompatibility::zcUnix)) {
+ log_warn ("VFSCopyFromLocal: Unable to set system compatibility of the ZIP archive to Unix");
+ }
+
try_again = FALSE;
s = exclude_leading_path_sep (sDstName);
if (! globs->zip->AddNewFile (sSrcName, s, CZipCompressor::levelDefault, CZipArchive::zipsmSafeSmart, globs->block_size)) {
@@ -1129,8 +1159,13 @@ VFSCopyFromLocal (struct TVFSGlobs *globs, const char *sSrcName, const char *sDs
}
globs->zip->CloseNewFile ();
- log_debug ("VFSCopyFromLocal: copy OK, archive closed = %d.", globs->zip->IsClosed ());
globs->archive_modified = TRUE;
+ log_debug ("VFSCopyFromLocal: copy OK, archive closed = %d.", globs->zip->IsClosed ());
+
+ if (! globs->in_copy_operation) {
+ globs->zip->FlushBuffers ();
+ globs->zip->Finalize (false);
+ }
/*
// Encrypt the file if archive contains any encrypted files
@@ -1229,6 +1264,11 @@ VFSOpenFile (struct TVFSGlobs *globs, const char *APath, int Mode, GError **erro
CZipFileHeader header;
gchar *s;
+ /* set system compatibility first */
+ if (! globs->zip->SetSystemCompatibility (ZipCompatibility::zcUnix)) {
+ log_warn ("VFSOpenFile: Unable to set system compatibility of the ZIP archive to Unix");
+ }
+
s = exclude_leading_path_sep (APath);
header.SetFileName (s);
header.SetSystemAttr (ZipPlatform::GetDefaultAttributes());
@@ -1298,7 +1338,10 @@ VFSCloseFile (struct TVFSGlobs *globs, TVFSFileDes FileDescriptor, GError **erro
globs->after_exception = FALSE;
if (globs->archive_modified) {
log_debug ("VFSCloseFile: archive modified, rebuilding the tree.");
- globs->zip->FlushBuffers ();
+ if (! globs->in_copy_operation) {
+ globs->zip->FlushBuffers ();
+ globs->zip->Finalize (false);
+ }
build_global_filelist (globs);
}
if (! b) {