# HG changeset patch # User Yuya Nishihara # Date 2015-08-09 07:09:41 # Node ID b12e00a05d57bbc9acb5117c392ebe8576c40891 # Parent 4f703dcc626f4118bf6643e5ea4d1c23d476d69f revset: prevent crash caused by empty group expression while optimizing "or" An empty group expression "()" generates None in AST, so it should be tested before destructuring a tuple. "A | ()" is still evaluated to an error because I'm not sure whether "()" represents an empty set or an empty expression (= a unit value). They are identical in "or" operation, but they should be evaluated differently in "and" operation. expression empty set unit value ---------- --------- ---------- () {} A A & () {} A A | () A A diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -2280,7 +2280,7 @@ def optimize(x, small): del ss[:] for y in x[1:]: w, t = optimize(y, False) - if t[0] == 'string' or t[0] == 'symbol': + if t is not None and (t[0] == 'string' or t[0] == 'symbol'): ss.append((w, t)) continue flushss() diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -1144,6 +1144,20 @@ test that chained `or` operations make b 4 5 +no crash by empty group "()" while optimizing `or` operations + + $ try --optimize '0|()' + (or + ('symbol', '0') + (group + None)) + * optimized: + (or + ('symbol', '0') + None) + hg: parse error: missing argument + [255] + test that chained `or` operations never eat up stack (issue4624) (uses `0:1` instead of `0` to avoid future optimization of trivial revisions)