Patchwork [1,of,2,STABLE] revset: prevent crash caused by empty group expression while optimizing "and"

login
register
mail settings
Submitter Yuya Nishihara
Date Aug. 9, 2015, 8:33 a.m.
Message ID <56d3f5a9c5021efa4245.1439109206@mimosa>
Download mbox | patch
Permalink /patch/10183/
State Accepted
Headers show

Comments

Yuya Nishihara - Aug. 9, 2015, 8:33 a.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1439103996 -32400
#      Sun Aug 09 16:06:36 2015 +0900
# Branch stable
# Node ID 56d3f5a9c5021efa42454e30a2748aab1e2924d2
# Parent  f4386cb3252ef6eb1b2911178d9207bf465effec
revset: prevent crash caused by empty group expression while optimizing "and"

An empty group expression "()" generates None in AST, so the optimizer have
to test it before destructuring a tuple. The error message, "missing argument",
is somewhat obscure, but it should be better than crash.

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -2245,8 +2245,10 @@  def optimize(x, small):
         # (::x and not ::y)/(not ::y and ::x) have a fast path
         def isonly(revs, bases):
             return (
-                revs[0] == 'func'
+                revs is not None
+                and revs[0] == 'func'
                 and getstring(revs[1], _('not a symbol')) == 'ancestors'
+                and bases is not None
                 and bases[0] == 'not'
                 and bases[1][0] == 'func'
                 and getstring(bases[1][1], _('not a symbol')) == 'ancestors')
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -1230,6 +1230,23 @@  check that conversion to only works
   5
   6
 
+no crash by empty group "()" while optimizing to "only()"
+
+  $ try --optimize '::1 and ()'
+  (and
+    (dagrangepre
+      ('symbol', '1'))
+    (group
+      None))
+  * optimized:
+  (and
+    None
+    (func
+      ('symbol', 'ancestors')
+      ('symbol', '1')))
+  hg: parse error: missing argument
+  [255]
+
 we can use patterns when searching for tags
 
   $ log 'tag("1..*")'