D3445: dispatch: validate return type from dispatch() return value
indygreg (Gregory Szorc)
phabricator at mercurial-scm.org
Sat May 12 00:48:27 EDT 2018
indygreg updated this revision to Diff 8654.
indygreg edited the summary of this revision.
indygreg retitled this revision from "dispatch: shore up exit handling" to "dispatch: validate return type from dispatch() return value".
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D3445?vs=8460&id=8654
REVISION DETAIL
https://phab.mercurial-scm.org/D3445
AFFECTED FILES
mercurial/dispatch.py
tests/test-dispatch.t
CHANGE DETAILS
diff --git a/tests/test-dispatch.t b/tests/test-dispatch.t
--- a/tests/test-dispatch.t
+++ b/tests/test-dispatch.t
@@ -263,48 +263,28 @@
[42]
$ hg exit returnstring 'some message'
- Traceback (most recent call last):
- File "*/hg", line *, in <module> (glob)
- dispatch.run()
- File "*/mercurial/dispatch.py", line *, in run (glob)
- sys.exit(status & 255)
- TypeError: unsupported operand type(s) for &: 'str' and 'int'
- [1]
+ error: received non-integer status code: 'some message'
+ [255]
$ hg exit returnnone
$ hg exit returnempty
$ hg exit returndict
- Traceback (most recent call last):
- File "*/hg", line *, in <module> (glob)
- dispatch.run()
- File "*/mercurial/dispatch.py", line *, in run (glob)
- sys.exit(status & 255)
- TypeError: unsupported operand type(s) for &: 'dict' and 'int'
- [1]
+ error: received non-integer status code: {'key1': 'value1'}
+ [255]
$ hg exit systemexitint 42
[42]
$ hg exit systemexitstring 'failure message'
- Traceback (most recent call last):
- File "*/hg", line *, in <module> (glob)
- dispatch.run()
- File "*/mercurial/dispatch.py", line *, in run (glob)
- sys.exit(status & 255)
- TypeError: unsupported operand type(s) for &: 'str' and 'int'
- [1]
+ error: received non-integer status code: 'failure message'
+ [255]
$ hg exit systemexitnoarg
$ hg exit systemexitnone
$ hg exit systemexitdict
- Traceback (most recent call last):
- File "*/hg", line *, in <module> (glob)
- dispatch.run()
- File "*/mercurial/dispatch.py", line *, in run (glob)
- sys.exit(status & 255)
- TypeError: unsupported operand type(s) for &: 'dict' and 'int'
- [1]
+ error: received non-integer status code: {'key1': 'value1'}
+ [255]
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -88,6 +88,20 @@
err = None
try:
status = dispatch(req) or 0
+
+ # dispatch() should return an int or None. Python allows the
+ # value to sys.exit() to be special. We don't want to fall back to
+ # this handling, so we normalize to an int.
+ if not isinstance(status, int):
+ if util.safehasattr(req.ui, 'ferr'):
+ # If this raises, things are *really* messed up. We're
+ # OK with a possibly uncaught exception in this case
+ # because we're already in an exceptional code path.
+ req.ui.ferr.write('error: received non-integer status '
+ 'code: %r\n' % status)
+
+ status = -1
+
except error.StdioError as e:
err = e
status = -1
To: indygreg, #hg-reviewers
Cc: yuja, mercurial-devel
More information about the Mercurial-devel
mailing list