Commit 16cfe2d3 authored by Rob Swindell's avatar Rob Swindell 💬
Browse files

Add overwrite argument to extract_file_from_archive and Archive.extract

Previously, extracted files were always overwritten (so that is the "default" for Archive.extract() and mostly what I'm specifying in the C/C++ code by default now), but this caused a problem with DIZ extraction: archives that contained multiple DIZ files (e.g in sub-directories), the last to be extracted would be used. A maximum of 3 DIZs can be extracted, so it would usually be the 3rd DIZ in the archive if there were that many.

Another solution would be to *only* extract DIZ files from the root of the archive and I should look into that as well, but the always-overwrite behavior also seemed to be wrong, so that *also* needed fixing (allow caller to control behavior).

This fixes issue #317, at least for archives where the root DIZ exists *before* any nested DIZ files. I'll have to try and create a purposeful archive to test the other conditions (where the root DIZ would appear *after* the nested DIZ(s)).
parent 76720fc1
Pipeline #2553 passed with stage
in 9 minutes and 27 seconds
......@@ -809,7 +809,7 @@ long create_archive(const char* archive, const char* format
}
long extract_files_from_archive(const char* archive, const char* outdir, const char* allowed_filename_chars
,bool with_path, long max_files, str_list_t file_list, char* error, size_t maxerrlen)
,bool with_path, bool overwrite, long max_files, str_list_t file_list, char* error, size_t maxerrlen)
{
int result;
struct archive *ar;
......@@ -884,6 +884,8 @@ long extract_files_from_archive(const char* archive, const char* outdir, const c
SAFECOPY(fpath, outdir);
backslash(fpath);
SAFECAT(fpath, pathname);
if(!overwrite && fexist(fpath))
continue;
FILE* fp = fopen(fpath, "wb");
if(fp == NULL) {
char err[256];
......@@ -945,6 +947,7 @@ bool extract_diz(scfg_t* cfg, file_t* f, str_list_t diz_fnames, char* path, size
,/* outdir: */cfg->temp_dir
,/* allowed_filename_chars: */NULL /* any */
,/* with_path: */false
,/* overwrite: */false
,/* max_files: */strListCount(diz_fnames)
,/* file_list: */diz_fnames
,/* error: */NULL, 0) >= 0) {
......
......@@ -72,7 +72,7 @@ DLLEXPORT long create_archive(const char* archive, const char* format
,bool with_path, str_list_t file_list, char* error, size_t maxerrlen);
DLLEXPORT char* cmdstr(scfg_t*, user_t*, const char* instr, const char* fpath, const char* fspec, char* cmd, size_t);
DLLEXPORT long extract_files_from_archive(const char* archive, const char* outdir, const char* allowed_filename_chars
,bool with_path, long max_files, str_list_t file_list, char* error, size_t);
,bool with_path, bool overwrite, long max_files, str_list_t file_list, char* error, size_t);
DLLEXPORT int archive_type(const char* archive, char* str, size_t size);
extern const char* supported_archive_formats[];
......
......@@ -109,6 +109,7 @@ js_extract(JSContext *cx, uintN argc, jsval *arglist)
char* allowed_filename_chars = SAFEST_FILENAME_CHARS;
str_list_t file_list = NULL;
bool with_path = false;
bool overwrite = true;
int32 max_files = 0;
char error[256] = "";
jsrefcount rc;
......@@ -136,6 +137,10 @@ js_extract(JSContext *cx, uintN argc, jsval *arglist)
allowed_filename_chars = NULL; // We trust this archive
argn++;
}
if(argc > argn && JSVAL_IS_BOOLEAN(argv[argn])) {
overwrite = JSVAL_TO_BOOLEAN(argv[argn]);
argn++;
}
if(argc > argn && JSVAL_IS_NUMBER(argv[argn])) {
if(!JS_ValueToInt32(cx, argv[argn], &max_files)) {
free(outdir);
......@@ -154,7 +159,7 @@ js_extract(JSContext *cx, uintN argc, jsval *arglist)
rc = JS_SUSPENDREQUEST(cx);
long extracted = extract_files_from_archive(filename, outdir, allowed_filename_chars
,with_path, (ulong)max_files, file_list, error, sizeof(error));
,with_path, overwrite, (ulong)max_files, file_list, error, sizeof(error));
strListFree(&file_list);
free(outdir);
JS_RESUMEREQUEST(cx, rc);
......@@ -538,7 +543,7 @@ static jsSyncMethodSpec js_archive_functions[] = {
,31900
},
{ "extract", js_extract, 1, JSTYPE_NUMBER
,JSDOCSTR("output_directory [,boolean with_path = false] [,number max_files = 0] [,string file/pattern [...]]")
,JSDOCSTR("output_directory [,boolean with_path = false] [,boolean overwrite = true] [,number max_files = 0] [,string file/pattern [...]]")
,JSDOCSTR("Extract files from an archive to specified output directory.<br>"
"Returns the number of files extracted.<br>"
"Will throw exception upon error.")
......
......@@ -73,6 +73,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack)
,/* outdir: */cfg.temp_dir
,/* allowed_filename_chars: */NULL /* any */
,/* with_path: */false
,/* overwrite: */true
,/* max_files: */0 /* unlimited */
,/* file_list: */NULL /* all files */
,error, sizeof(error));
......
......@@ -67,6 +67,7 @@ bool sbbs_t::pack_rep(uint hubnum)
,/* outdir: */cfg.temp_dir
,/* allowed_filename_chars: */NULL /* any */
,/* with_path: */false
,/* overwrite: */true
,/* max_files: */0 /* unlimited */
,/* file_list: */NULL /* all files */
,error, sizeof(error));
......
......@@ -2266,7 +2266,7 @@ int unpack(const char *infile, const char* outdir)
long file_count;
file_count = extract_files_from_archive(infile, outdir
,/* allowed_filename_chars: */SAFEST_FILENAME_CHARS, /* with_path */false
,/* allowed_filename_chars: */SAFEST_FILENAME_CHARS, /* with_path */false, /* overwrite: */true
,/* max_files: */0, /* file_list = ALL */NULL, error, sizeof(error));
if(file_count > 0) {
lprintf(LOG_DEBUG, "libarchive extracted %lu files from %s", file_count, infile);
......
......@@ -80,6 +80,7 @@ bool sbbs_t::unpack_qwk(char *packet,uint hubnum)
,/* outdir: */cfg.temp_dir
,/* allowed_filename_chars: */NULL /* any */
,/* with_path: */false
,/* overwrite: */true
,/* max_files: */0 /* unlimited */
,/* file_list: */NULL /* all files */
,error, sizeof(error));
......
......@@ -76,6 +76,7 @@ bool sbbs_t::unpack_rep(char* repfile)
,/* outdir: */cfg.temp_dir
,/* allowed_filename_chars: */SAFEST_FILENAME_CHARS
,/* with_path: */false
,/* overwrite: */true
,/* max_files */1000
,/* file_list: */NULL /* all files */
,error, sizeof(error));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment