From 843bad187cfe40c9714c6deb5170d055021a462e Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Tue, 19 Dec 2017 11:20:57 +1300 Subject: [PATCH] types: add validation to partial parser --- mitmproxy/command.py | 26 +++++++++++++++++++++++--- test/mitmproxy/test_command.py | 30 +++++++++++++++--------------- test/mitmproxy/test_types.py | 1 + 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/mitmproxy/command.py b/mitmproxy/command.py index f978b25b6..b645798df 100644 --- a/mitmproxy/command.py +++ b/mitmproxy/command.py @@ -110,7 +110,11 @@ class Command: ParseResult = typing.NamedTuple( "ParseResult", - [("value", str), ("type", typing.Type)], + [ + ("value", str), + ("type", typing.Type), + ("valid", bool), + ], ) @@ -161,13 +165,29 @@ class CommandManager(mitmproxy.types._CommandBase): params.extend(self.commands[parts[i]].paramtypes) elif params: typ = params.pop(0) - # FIXME: Do we need to check that Arg is positional? if typ == mitmproxy.types.Cmd and params and params[0] == mitmproxy.types.Arg: if parts[i] in self.commands: params[:] = self.commands[parts[i]].paramtypes else: typ = str - parse.append(ParseResult(value=parts[i], type=typ)) + + to = mitmproxy.types.CommandTypes.get(typ, None) + valid = False + if to: + try: + to.parse(self, typ, parts[i]) + except exceptions.TypeError: + valid = False + else: + valid = True + + parse.append( + ParseResult( + value=parts[i], + type=typ, + valid=valid, + ) + ) return parse def call_args(self, path: str, args: typing.Sequence[str]) -> typing.Any: diff --git a/test/mitmproxy/test_command.py b/test/mitmproxy/test_command.py index 608a08b60..75b100985 100644 --- a/test/mitmproxy/test_command.py +++ b/test/mitmproxy/test_command.py @@ -78,46 +78,46 @@ class TestCommand: [ "foo bar", [ - command.ParseResult(value = "foo", type = mitmproxy.types.Cmd), - command.ParseResult(value = "bar", type = str) + command.ParseResult(value = "foo", type = mitmproxy.types.Cmd, valid = True), + command.ParseResult(value = "bar", type = str, valid = True) ], ], [ "foo 'bar", [ - command.ParseResult(value = "foo", type = mitmproxy.types.Cmd), - command.ParseResult(value = "'bar", type = str) + command.ParseResult(value = "foo", type = mitmproxy.types.Cmd, valid = True), + command.ParseResult(value = "'bar", type = str, valid = True) ] ], - ["a", [command.ParseResult(value = "a", type = mitmproxy.types.Cmd)]], - ["", [command.ParseResult(value = "", type = mitmproxy.types.Cmd)]], + ["a", [command.ParseResult(value = "a", type = mitmproxy.types.Cmd, valid = True)]], + ["", [command.ParseResult(value = "", type = mitmproxy.types.Cmd, valid = True)]], [ "cmd3 1", [ - command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd), - command.ParseResult(value = "1", type = int), + command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd, valid = True), + command.ParseResult(value = "1", type = int, valid = True), ] ], [ "cmd3 ", [ - command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd), - command.ParseResult(value = "", type = int), + command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd, valid = True), + command.ParseResult(value = "", type = int, valid = False), ] ], [ "subcommand ", [ - command.ParseResult(value = "subcommand", type = mitmproxy.types.Cmd), - command.ParseResult(value = "", type = mitmproxy.types.Cmd), + command.ParseResult(value = "subcommand", type = mitmproxy.types.Cmd, valid = True), + command.ParseResult(value = "", type = mitmproxy.types.Cmd, valid = True), ] ], [ "subcommand cmd3 ", [ - command.ParseResult(value = "subcommand", type = mitmproxy.types.Cmd), - command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd), - command.ParseResult(value = "", type = int), + command.ParseResult(value = "subcommand", type = mitmproxy.types.Cmd, valid = True), + command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd, valid = True), + command.ParseResult(value = "", type = int, valid = False), ] ], ] diff --git a/test/mitmproxy/test_types.py b/test/mitmproxy/test_types.py index df9bd4e08..5b1dd3a21 100644 --- a/test/mitmproxy/test_types.py +++ b/test/mitmproxy/test_types.py @@ -182,6 +182,7 @@ def test_data(): assert b.is_valid(tctx.master.commands, mitmproxy.types.Data, []) is True assert b.is_valid(tctx.master.commands, mitmproxy.types.Data, [["x"]]) is True assert b.is_valid(tctx.master.commands, mitmproxy.types.Data, [[b"x"]]) is True + assert b.is_valid(tctx.master.commands, mitmproxy.types.Data, [[1]]) is False with pytest.raises(mitmproxy.exceptions.TypeError): b.parse(tctx.master.commands, mitmproxy.types.Data, "foo") with pytest.raises(mitmproxy.exceptions.TypeError):