]> git.eshelyaron.com Git - emacs.git/commit
Fix pcase 'rx' pattern match-data bug
authorMattias Engdegård <mattiase@acm.org>
Sun, 28 Feb 2021 12:06:24 +0000 (13:06 +0100)
committerMattias Engdegård <mattiase@acm.org>
Sun, 28 Feb 2021 12:06:24 +0000 (13:06 +0100)
commitbdea1883cc8feb8a607c3d05191e7dc8d12f0aa0
tree93d93a3c7f2fc7b0aa821a128be8c306645a7519
parentaad8ffafa89fe46ff5d63bd0127274f74019d50f
Fix pcase 'rx' pattern match-data bug

The pcase 'rx' pattern would in some cases allow the match data to be
clobbered before it is read.  For example:

  (pcase "PQR"
    ((and (rx (let a nonl)) (rx ?z)) (list 'one a))
    ((rx (let b ?Q))                 (list 'two b)))

The above returned (two "P") instead of the correct (two "Q").
This occurred because the calls to string-match and match-string were
presented as separate patterns to pcase, which would interleave them
with other patterns.

As a remedy, combine string matching and match-data extraction into a
single pcase pattern.  This introduces a slight inefficiency for two
or more submatches as they are grouped into a list structure which
then has to be destructured.

Found by Stefan Monnier.  See discussion at
https://lists.gnu.org/archive/html/emacs-devel/2021-02/msg02010.html

* lisp/emacs-lisp/rx.el (rx--reduce-right): New helper.
(rx [pcase macro]): Combine string-match and match-string calls into a
single pcase pattern.
* test/lisp/emacs-lisp/rx-tests.el (rx-pcase): Add test cases.
lisp/emacs-lisp/rx.el
test/lisp/emacs-lisp/rx-tests.el