types: add validation to partial parser

This commit is contained in:
Aldo Cortesi 2017-12-19 11:20:57 +13:00
parent 6563feaf05
commit 843bad187c
3 changed files with 39 additions and 18 deletions

View File

@ -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:

View File

@ -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),
]
],
]

View File

@ -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):