From patchwork Sun Aug 9 08:33:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [2, of, 2, STABLE] revset: prevent crash caused by empty group expression while optimizing "or" From: Yuya Nishihara X-Patchwork-Id: 10184 Message-Id: <56a853ed34fbd7556296.1439109207@mimosa> To: mercurial-devel@selenic.com Date: Sun, 09 Aug 2015 17:33:27 +0900 # HG changeset patch # User Yuya Nishihara # Date 1439104181 -32400 # Sun Aug 09 16:09:41 2015 +0900 # Branch stable # Node ID 56a853ed34fbd755629692cec73555913e8bcb42 # Parent 56d3f5a9c5021efa42454e30a2748aab1e2924d2 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)