commit f2cb5b36b0ed714487e08f5c9b7c2244ca134df6
parent cda3dae3ec9771b9f9581d14481e5c3cf67110b3
Author: wwp <subscript@free.fr>
Date: Fri, 7 Mar 2025 15:19:34 +0100
Mail Archiver plug-in: add support for ZSTD (libarchive >= 3.4.0).
Fix a possible buffer overrun.
Diffstat:
6 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/src/plugins/archive/archiver.c b/src/plugins/archive/archiver.c
@@ -160,6 +160,9 @@ const gchar* plugin_desc(void) {
#if ARCHIVE_VERSION_NUMBER >= 3001900
"\tLZ4\n"
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+ "\tZSTD\n"
+#endif
);
}
return plugin_description;
diff --git a/src/plugins/archive/archiver_gtk.c b/src/plugins/archive/archiver_gtk.c
@@ -264,6 +264,12 @@ static COMPRESS_METHOD get_compress_method(GSList* btn) {
return LZ4;
}
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3001900
+ else if (strcmp("ZSTD", name) == 0) {
+ debug_print("ZSTD compression enabled\n");
+ return LZ4;
+ }
+#endif
else if (strcmp("NONE", name) == 0) {
debug_print("Compression disabled\n");
return NO_COMPRESS;
@@ -716,6 +722,11 @@ static void show_result(struct ArchivePage* page) {
method = g_strdup("LZ4");
break;
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3001900
+ case ZSTD:
+ method = g_strdup("ZSTD");
+ break;
+#endif
case NO_COMPRESS:
method = g_strdup("No Compression");
break;
@@ -1021,6 +1032,9 @@ void archiver_gtk_show(void) {
#if ARCHIVE_VERSION_NUMBER >= 3001900
GtkWidget* lz4_radio_btn;
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3001900
+ GtkWidget* zstd_radio_btn;
+#endif
GtkWidget* no_radio_btn;
GtkWidget* shar_radio_btn;
GtkWidget* pax_radio_btn;
@@ -1172,6 +1186,14 @@ void archiver_gtk_show(void) {
archiver_set_tooltip(lz4_radio_btn, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "LZ4"));
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+ zstd_radio_btn = gtk_radio_button_new_with_mnemonic_from_widget(
+ GTK_RADIO_BUTTON(gzip_radio_btn), "ZZSTD");
+ gtk_widget_set_name(zstd_radio_btn, "ZSTD");
+ gtk_box_pack_start(GTK_BOX(hbox1), zstd_radio_btn, FALSE, FALSE, 0);
+ archiver_set_tooltip(zstd_radio_btn, g_strdup_printf(_("Choose this option to use %s compression for the archive"), "ZSTD"));
+#endif
+
no_radio_btn = gtk_radio_button_new_with_mnemonic_from_widget(
GTK_RADIO_BUTTON(gzip_radio_btn), _("_None"));
gtk_widget_set_name(no_radio_btn, "NONE");
@@ -1220,6 +1242,11 @@ void archiver_gtk_show(void) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lz4_radio_btn), TRUE);
break;
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+ case COMPRESSION_ZSTD:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(zstd_radio_btn), TRUE);
+ break;
+#endif
case COMPRESSION_NONE:
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(no_radio_btn), TRUE);
break;
diff --git a/src/plugins/archive/archiver_prefs.c b/src/plugins/archive/archiver_prefs.c
@@ -66,6 +66,9 @@ struct ArchiverPrefsPage {
#if ARCHIVE_VERSION_NUMBER >= 3001900
GtkWidget *lz4_radiobtn;
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+ GtkWidget *zstd_radiobtn;
+#endif
GtkWidget *none_radiobtn;
GtkWidget *tar_radiobtn;
GtkWidget *shar_radiobtn;
@@ -190,6 +193,9 @@ static void create_archiver_prefs_page(PrefsPage * _page,
#if ARCHIVE_VERSION_NUMBER >= 3001900
GtkWidget *lz4_radiobtn;
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+ GtkWidget *zstd_radiobtn;
+#endif
GtkWidget *none_radiobtn;
GSList *format_group = NULL;
GtkWidget *tar_radiobtn;
@@ -309,6 +315,14 @@ static void create_archiver_prefs_page(PrefsPage * _page,
archiver_set_tooltip(lz4_radiobtn, g_strdup_printf(_("Choose this option to use %s compression by default"), "LZ4"));
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+ zstd_radiobtn = gtk_radio_button_new_with_label(compression_group, "ZSTD");
+ compression_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(zstd_radiobtn));
+ gtk_widget_show(zstd_radiobtn);
+ gtk_box_pack_start(GTK_BOX (hbox1), zstd_radiobtn, FALSE, FALSE, 0);
+ archiver_set_tooltip(zstd_radiobtn, g_strdup_printf(_("Choose this option to use %s compression by default"), "ZSTD"));
+#endif
+
none_radiobtn = gtk_radio_button_new_with_label(compression_group, _("None"));
compression_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(none_radiobtn));
gtk_widget_show(none_radiobtn);
@@ -354,6 +368,11 @@ static void create_archiver_prefs_page(PrefsPage * _page,
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lz4_radiobtn), TRUE);
break;
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+ case COMPRESSION_ZSTD:
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(zstd_radiobtn), TRUE);
+ break;
+#endif
case COMPRESSION_NONE:
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(none_radiobtn), TRUE);
break;
@@ -460,6 +479,9 @@ static void create_archiver_prefs_page(PrefsPage * _page,
#if ARCHIVE_VERSION_NUMBER >= 3001900
page->lz4_radiobtn = lz4_radiobtn;
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+ page->zstd_radiobtn = zstd_radiobtn;
+#endif
page->none_radiobtn = none_radiobtn;
page->tar_radiobtn = tar_radiobtn;
page->shar_radiobtn = shar_radiobtn;
@@ -514,6 +536,10 @@ static void save_archiver_prefs(PrefsPage * _page)
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->lz4_radiobtn)))
archiver_prefs.compression = COMPRESSION_LZ4;
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+ else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->zstd_radiobtn)))
+ archiver_prefs.compression = COMPRESSION_ZSTD;
+#endif
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->none_radiobtn)))
archiver_prefs.compression = COMPRESSION_NONE;
diff --git a/src/plugins/archive/archiver_prefs.h b/src/plugins/archive/archiver_prefs.h
@@ -44,6 +44,9 @@ typedef enum {
#if ARCHIVE_VERSION_NUMBER >= 3001900
COMPRESSION_LZ4,
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3001900
+ COMPRESSION_ZSTD,
+#endif
COMPRESSION_NONE
} CompressionType;
diff --git a/src/plugins/archive/libarchive_archive.c b/src/plugins/archive/libarchive_archive.c
@@ -532,6 +532,12 @@ const gchar* archive_create(const char* archive_name, GSList* files,
return archive_error_string(arch);
break;
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+ case ZSTD:
+ if (archive_write_add_filter_zstd(arch) != ARCHIVE_OK)
+ return archive_error_string(arch);
+ break;
+#endif
case NO_COMPRESS:
#if ARCHIVE_VERSION_NUMBER < 3000000
if (archive_write_set_compression_none(arch) != ARCHIVE_OK)
@@ -707,7 +713,7 @@ void archive_scan_folder(const char* dir) {
int main(int argc, char** argv) {
char* archive = NULL;
- char buf[PATH_MAX];
+ char buf[PATH_MAX*2];
int pid;
int opt;
int perm = ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME |
diff --git a/src/plugins/archive/libarchive_archive.h b/src/plugins/archive/libarchive_archive.h
@@ -46,6 +46,9 @@ enum _COMPRESS_METHOD {
#if ARCHIVE_VERSION_NUMBER >= 3001900
LZ4,
#endif
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+ ZSTD,
+#endif
NO_COMPRESS
};