branch: externals/relint commit d0fa8a8d13263c09962d5c8e9f5da644a1f78843 Author: Mattias Engdegård <matti...@acm.org> Commit: Mattias Engdegård <matti...@acm.org>
Fix false positives in regexp provenance checks Detect more common functions which harmlessly absorb regexps without returning them. --- relint.el | 30 +++++++++++++++++++++++++++--- test/6.elisp | 6 +++++- test/6.expected | 33 +++++++++++++++++---------------- 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/relint.el b/relint.el index 7a45323..81859ac 100644 --- a/relint.el +++ b/relint.el @@ -1284,12 +1284,36 @@ EXPANDED is a list of expanded functions, to prevent recursion." ((atom expr) nil) ((memq (car expr) relint--regexp-returning-functions) (list (car expr))) - ((memq (car expr) '(looking-at re-search-forward re-search-backward - string-match string-match-p looking-back looking-at-p)) + ((memq (car expr) + ;; These forms never produce regexps at all, but are listed here + ;; to prevent false positives since their bodies often do. + '(while + looking-at re-search-forward re-search-backward + string-match string-match-p looking-back looking-at-p + replace-regexp + query-replace-regexp + posix-looking-at posix-search-backward + posix-search-forward + posix-string-match + search-forward-regexp search-backward-regexp + kill-matching-buffers + keep-lines flush-lines how-many + delete-matching-lines delete-non-matching-lines + count-matches + s-matches? s-matches-p s-matched-positions-all + s-count-matches s-count-matches-all)) nil) ((null (cdr (last expr))) (let* ((head (car expr)) - (args (if (memq head '(if when unless while)) + (args + (if (memq head + ;; These forms may generate regexps but the provenance + ;; of their first argument is irrelevant. + ;; This list, too, could be expanded vastly. + '(if when unless + replace-regexp-in-string + s-match-strings-all s-match s-slice-at + s-split s-split-up-to)) (cddr expr) (cdr expr))) (alias (assq head relint--alias-defs))) diff --git a/test/6.elisp b/test/6.elisp index cbbdf4b..2180df6 100644 --- a/test/6.elisp +++ b/test/6.elisp @@ -17,7 +17,11 @@ (format "[%s]" (regexp-quote x)) (format "[%s]" (myrefun y)) (format "[%s]" (rx ?a "b" nonl)) - (format "[%s]" (rx-to-string z)))) + (format "[%s]" (rx-to-string z)) + (format "[%s]" (f (string-match (regexp-quote x) a))) ; ok + (format "[%s]" (f (replace-regexp-in-string (regexp-quote x) a b))) ; ok + (format "[%s]" (f (replace-regexp-in-string a b (regexp-quote x)))) ; bad + )) ;; Test skip-chars (defun test-skip-chars (x y z) diff --git a/test/6.expected b/test/6.expected index 0e8728e..e8851d5 100644 --- a/test/6.expected +++ b/test/6.expected @@ -8,27 +8,28 @@ 6.elisp:18:19: Value from `regexp-opt' cannot be spliced into `[...]' 6.elisp:19:19: Value from `rx' cannot be spliced into `[...]' 6.elisp:20:19: Value from `rx-to-string' cannot be spliced into `[...]' -6.elisp:24:24: In call to skip-chars-forward: Suspect skip set framed in `[...]' (pos 0) +6.elisp:23:19: Value from `regexp-quote' cannot be spliced into `[...]' +6.elisp:28:24: In call to skip-chars-forward: Suspect skip set framed in `[...]' (pos 0) "[a-z]" ^ -6.elisp:25:26: In call to skip-chars-backward: Duplicated character `a' (pos 1) +6.elisp:29:26: In call to skip-chars-backward: Duplicated character `a' (pos 1) "aa" .^ -6.elisp:26:23: `some-re' cannot be used for arguments to `skip-chars-forward' -6.elisp:27:24: `regexp-quote' cannot be used for arguments to `skip-chars-backward' -6.elisp:28:23: `regexp-opt' cannot be used for arguments to `skip-chars-forward' -6.elisp:29:24: `rx' cannot be used for arguments to `skip-chars-backward' -6.elisp:30:23: `rx-to-string' cannot be used for arguments to `skip-chars-forward' -6.elisp:34:27: In call to skip-syntax-forward: Invalid char `s' in syntax string (pos 1) +6.elisp:30:23: `some-re' cannot be used for arguments to `skip-chars-forward' +6.elisp:31:24: `regexp-quote' cannot be used for arguments to `skip-chars-backward' +6.elisp:32:23: `regexp-opt' cannot be used for arguments to `skip-chars-forward' +6.elisp:33:24: `rx' cannot be used for arguments to `skip-chars-backward' +6.elisp:34:23: `rx-to-string' cannot be used for arguments to `skip-chars-forward' +6.elisp:38:27: In call to skip-syntax-forward: Invalid char `s' in syntax string (pos 1) "\\s-" ..^ -6.elisp:35:27: In call to skip-syntax-backward: Duplicated syntax code ` ' (pos 1) +6.elisp:39:27: In call to skip-syntax-backward: Duplicated syntax code ` ' (pos 1) "- " .^ -6.elisp:36:24: `some-re' cannot be used for arguments to `skip-syntax-forward' -6.elisp:37:25: `regexp-quote' cannot be used for arguments to `skip-syntax-backward' -6.elisp:38:24: `regexp-opt' cannot be used for arguments to `skip-syntax-forward' -6.elisp:39:25: `rx' cannot be used for arguments to `skip-syntax-backward' -6.elisp:40:24: `rx-to-string' cannot be used for arguments to `skip-syntax-forward' -6.elisp:64:23: `make-a-nice-regexp' cannot be used for arguments to `skip-chars-forward' -6.elisp:65:24: `make-something' cannot be used for arguments to `skip-chars-backward' +6.elisp:40:24: `some-re' cannot be used for arguments to `skip-syntax-forward' +6.elisp:41:25: `regexp-quote' cannot be used for arguments to `skip-syntax-backward' +6.elisp:42:24: `regexp-opt' cannot be used for arguments to `skip-syntax-forward' +6.elisp:43:25: `rx' cannot be used for arguments to `skip-syntax-backward' +6.elisp:44:24: `rx-to-string' cannot be used for arguments to `skip-syntax-forward' +6.elisp:68:23: `make-a-nice-regexp' cannot be used for arguments to `skip-chars-forward' +6.elisp:69:24: `make-something' cannot be used for arguments to `skip-chars-backward'