fix(allowlist): stop in-repo .gitsafeignore from disabling scanning

ober

41150d05cebab61c717cecf8ef26e5df2f67cc06

diff --git a/gitsafe/allowlist.ss b/gitsafe/allowlist.ss
index 514cd98..ccb5b26 100644
--- a/gitsafe/allowlist.ss
+++ b/gitsafe/allowlist.ss
@@ -71,8 +71,12 @@
         (read-file-lines path))))
 
   ;; --- Check if a file path matches any ignorefile pattern ---
+  ;; The ignorefile lives in the scanned (hostile) tree, so a match-all glob
+  ;; ("**") must not skip every file; such globs are refused here.
   (def (ignored-file? path ignore-patterns)
-    (any (lambda (glob) (glob-match? glob path))
+    (any (lambda (glob)
+           (and (not (match-all-glob? glob))
+                (glob-match? glob path)))
          ignore-patterns))
 
   ;; --- Check if a finding fingerprint is ignored exactly ---
diff --git a/gitsafe/scanner.ss b/gitsafe/scanner.ss
index 01ad286..9235280 100644
--- a/gitsafe/scanner.ss
+++ b/gitsafe/scanner.ss
@@ -694,11 +694,13 @@
     ;; Round up to the next MB for the warning message.
     (quotient (+ n (- (* 1024 1024) 1)) (* 1024 1024)))
 
-  (def (filter-ignored-findings findings ignore-pats config)
+  ;; Fingerprint suppression honors only a trusted baseline. Fingerprints from
+  ;; the in-repo .gitsafeignore are hostile input: a predictable
+  ;; file:pattern-id:line line would otherwise silence a known finding.
+  (def (filter-ignored-findings findings config)
     (filter (lambda (f)
-              (let ([fp (finding-fingerprint f)])
-                (not (or (ignored-fingerprint? fp ignore-pats)
-                         (member fp (gitsafe-config-baseline-fingerprints config))))))
+              (not (member (finding-fingerprint f)
+                           (gitsafe-config-baseline-fingerprints config))))
             findings))
 
   (def *git-empty-tree* "4b825dc642cb6eb9a060e54bf8d69288fbee4904")
@@ -782,7 +784,6 @@
                 [(list path hunks)
                  (scan-diff-hunks hunks config)]))
             work-items)
-          ignore-pats
           config))))
 
   ;; --- Top-level: scan push range ---
@@ -831,7 +832,6 @@
                     [(list path hunks)
                      (scan-diff-hunks hunks config)]))
                 work-items)
-              ignore-pats
               config)))))))
 
   (def (entry->string entry)
@@ -920,7 +920,6 @@
                     (scan-content path content config)
                     '())))
               to-scan)
-            ignore-pats
             config)
           (length to-scan)))))
 
diff --git a/test/test-gitsafe.ss b/test/test-gitsafe.ss
index c960aa2..ac95b39 100644
--- a/test/test-gitsafe.ss
+++ b/test/test-gitsafe.ss
@@ -328,6 +328,14 @@
           "config.env:generic-secret:13"
           '("config.env:generic-secret:12"))))
 
+    (test-case "ignored-file?: match-all glob ** does not skip files"
+      ;; A hostile .gitsafeignore line "**" must not skip every path.
+      (check-equal? #f (ignored-file? "src/secret.env" '("**")))
+      (check-equal? #f (ignored-file? "a/b/c.txt" '("**")))
+      ;; Narrow ignore globs still work.
+      (check-equal? #t (ignored-file? "vendor/foo.go" '("vendor/**")))
+      (check-equal? #f (ignored-file? "src/main.ss" '("vendor/**"))))
+
   ))
 
 ;; ============================================================
@@ -742,6 +750,33 @@
                                        findings)])
         (check-equal? '() entropy-findings)))
 
+    (test-case ".gitsafeignore ** does not skip files (integration)"
+      ;; A hostile in-repo .gitsafeignore containing "**" must not cause all
+      ;; files to be skipped; the secret is still scanned and reported.
+      (let ([ignore-path ".gitsafeignore"])
+        (write-test-file! ignore-path "**\n")
+        (let* ([c (default-config)]
+               [findings (scan-files '("test/fixtures/fake-secrets.txt") c)])
+          (delete-test-file! ignore-path)
+          (check-predicate findings pair?))))
+
+    (test-case ".gitsafeignore fingerprint line from scanned tree does not suppress"
+      ;; Fingerprint suppressions must come from a trusted source; a
+      ;; predictable file:pattern-id:line entry in the in-repo .gitsafeignore
+      ;; must not silence the finding.
+      (let* ([ignore-path ".gitsafeignore"]
+             [target "test/fixtures/tmp-fp-secret.env"]
+             [fp (finding-fingerprint-value target 'aws-access-key 1)])
+        (write-test-file! target "AKIAIOSFODNN7EXAMPLE\n")
+        (write-test-file! ignore-path (string-append fp "\n"))
+        (let* ([c (default-config)]
+               [findings (scan-files (list target) c)]
+               [aws (filter (lambda (f) (eq? (finding-pattern-id f) 'aws-access-key))
+                            findings)])
+          (delete-test-file! ignore-path)
+          (delete-test-file! target)
+          (check-predicate aws pair?))))
+
   ))
 
 ;; ============================================================