Add checks to avoid removing backup files in scan_incoming
authorJacob Bachmeyer <jcb@gnu.org>
Fri, 18 Nov 2022 02:43:51 +0000 (20:43 -0600)
committerJacob Bachmeyer <jcb@gnu.org>
Fri, 18 Nov 2022 02:43:51 +0000 (20:43 -0600)
Also update internal documentation and adjust testsuite to properly cover
the new edge case.

gatekeeper.pl
testsuite/gatekeeper.all/00_idle.exp

index 42ea8e68ce743fe85351b560d1b969b9c3c54bbb..62f85b45eb1b660d7bd12dcd1a582c3bc3fcc18a 100755 (executable)
@@ -1707,12 +1707,15 @@ sub scan_incoming {
  ENT: while (defined($_ = readdir INCOMING)) {
     next ENT if m/^[.]{1,2}$/; # skip . and .. entries
     # require acceptable filenames
-    unless (length($_) <= MAX_FILE_NAME_LEN && /^($RE_filename_here)$/) {
+    unless (length($_) <= MAX_FILE_NAME_LEN && m/^($RE_filename_here)$/) {
       m/^(.*)$/;       # untaint the value
-      push @trash, File::Spec->catfile($directory, $1); $badname_count++;
       # This is safe for unlink (which is all we will do with @trash)
       # because the filename came from a directory entry, so it must be a
       # valid filename and cannot indicate directory traversal.
+      unless (m/^[.]$RE_filename_here$/) {
+       # do not unlink backup files left by cleanup and cleanup_dir
+       push @trash, File::Spec->catfile($directory, $1); $badname_count++;
+      }
       next ENT
     }
     my $ent = $1;      # if we get here, $RE_filename_here matched above
@@ -2599,8 +2602,7 @@ sub execute_commands {
 Remove all files older than one day from DIRECTORY.
 
 As a precaution against data loss, "removed" files are actually simply
-renamed to have a leading dot.  Note that, for the inbox directory,
-scan_incoming will remove those files on the next run.
+renamed to have a leading dot.
 
 =cut
 
@@ -2635,8 +2637,7 @@ sub cleanup_dir {
 Remove FILES from the inbox, scratch, and staging directories.
 
 As a precaution against data loss, "removed" files are actually simply
-renamed to have a leading dot.  Note that, for the inbox directory,
-scan_incoming will remove those files on the next run.
+renamed to have a leading dot.
 
 =cut
 
index 4b3c5eeb00a64b5774187207ff5bda3c7c98c78f..d6223c0cb4e2fc22c5e2e28d2ac37269dc8a9f16 100644 (file)
@@ -58,11 +58,13 @@ foreach file {
 
 # files which are to be rejected, ignored, and removed
 foreach file {
-    x=x .abcfoobar -abcfoobar x;x \\~xax x*x x:x x?x ;xax _x +x
+    x=x .abcfoobar ..abcfoobar -abcfoobar x;x \\~xax x*x x:x x?x ;xax _x +x
 } {
     put_file [file join $tenv incoming ${file}] "bogus input $file\n"
     age_file [file join $tenv incoming ${file}] "3 minutes ago"
 }
+# ... except for .abcfoobar, which cleanup would produce when removing a
+#     file named "abcfoobar", which is an acceptable name
 
 start_test_services $tenv
 run_upload_batch_test
@@ -71,7 +73,7 @@ stop_test_services
 analyze_file_tree $tenv "idle processing: bogus files" {
     incoming
 } files {
-    bogus1 bogus2 bogus3
+    bogus1 bogus2 bogus3 .abcfoobar
     bo_gus bo+gus bo-gus bo~gus bo.gus
 }
 analyze_file_tree $tenv "idle processing: bogus files" {
@@ -95,6 +97,7 @@ analyze_log $tenv "idle processing: bogus files" {
 
     !scan,x=x          "ignored file: x=x"
     !scan,.abcfoobar   "ignored file: .abcfoobar"
+    !scan,..abcfoobar  "ignored file: ..abcfoobar"
     !scan,-abcfoobar   "ignored file: -abcfoobar"
     !scan,x;x          "ignored file: x;x"
     !scan,~xax         "ignored file: ~xax "