mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2025-02-02 00:05:27 +00:00
Removed the custom lexer in favor of using pyparsing.
This commit is contained in:
parent
f2b118817e
commit
8972250167
@ -3,14 +3,13 @@
|
|||||||
"""
|
"""
|
||||||
import inspect
|
import inspect
|
||||||
import types
|
import types
|
||||||
import io
|
|
||||||
import typing
|
import typing
|
||||||
import textwrap
|
import textwrap
|
||||||
import functools
|
import functools
|
||||||
import sys
|
import sys
|
||||||
|
import pyparsing
|
||||||
|
|
||||||
from mitmproxy import exceptions
|
from mitmproxy import exceptions
|
||||||
from mitmproxy import lexer
|
|
||||||
import mitmproxy.types
|
import mitmproxy.types
|
||||||
|
|
||||||
|
|
||||||
@ -22,10 +21,6 @@ def verify_arg_signature(f: typing.Callable, args: list, kwargs: dict) -> None:
|
|||||||
raise exceptions.CommandError("command argument mismatch: %s" % v.args[0])
|
raise exceptions.CommandError("command argument mismatch: %s" % v.args[0])
|
||||||
|
|
||||||
|
|
||||||
def get_lexer(s):
|
|
||||||
return lexer.Lexer(s)
|
|
||||||
|
|
||||||
|
|
||||||
def typename(t: type) -> str:
|
def typename(t: type) -> str:
|
||||||
"""
|
"""
|
||||||
Translates a type to an explanatory string.
|
Translates a type to an explanatory string.
|
||||||
@ -79,6 +74,20 @@ class Command:
|
|||||||
return "%s %s%s" % (self.path, params, ret)
|
return "%s %s%s" % (self.path, params, ret)
|
||||||
|
|
||||||
def prepare_args(self, args: typing.Sequence[str]) -> typing.List[typing.Any]:
|
def prepare_args(self, args: typing.Sequence[str]) -> typing.List[typing.Any]:
|
||||||
|
|
||||||
|
# Arguments that are just blank spaces aren't really arguments
|
||||||
|
# We need to get rid of those. If the user intended to pass a sequence
|
||||||
|
# of spaces, it would come between quotes
|
||||||
|
clean_args = []
|
||||||
|
for a in args:
|
||||||
|
if isinstance(a, str):
|
||||||
|
if a.strip() != '':
|
||||||
|
clean_args.append(a)
|
||||||
|
else:
|
||||||
|
clean_args.append(a)
|
||||||
|
|
||||||
|
args = clean_args
|
||||||
|
|
||||||
verify_arg_signature(self.func, list(args), {})
|
verify_arg_signature(self.func, list(args), {})
|
||||||
|
|
||||||
remainder: typing.Sequence[str] = []
|
remainder: typing.Sequence[str] = []
|
||||||
@ -152,24 +161,36 @@ class CommandManager(mitmproxy.types._CommandBase):
|
|||||||
"""
|
"""
|
||||||
Parse a possibly partial command. Return a sequence of ParseResults and a sequence of remainder type help items.
|
Parse a possibly partial command. Return a sequence of ParseResults and a sequence of remainder type help items.
|
||||||
"""
|
"""
|
||||||
buf = io.StringIO(cmdstr)
|
|
||||||
parts: typing.List[str] = []
|
parts: typing.List[str] = []
|
||||||
lex = get_lexer(buf)
|
|
||||||
while 1:
|
rex = pyparsing.QuotedString("\"", escChar='\\', unquoteResults=False) |\
|
||||||
remainder = cmdstr[buf.tell():]
|
pyparsing.QuotedString("'", escChar='\\', unquoteResults=False) |\
|
||||||
try:
|
pyparsing.Combine(pyparsing.Literal('"') + pyparsing.Word(pyparsing.printables + " ") + pyparsing.StringEnd()) |\
|
||||||
t = lex.get_token()
|
pyparsing.Word(pyparsing.printables) |\
|
||||||
except ValueError:
|
pyparsing.Word(' ')
|
||||||
parts.append(remainder)
|
|
||||||
break
|
rex = rex.copy().leaveWhitespace()
|
||||||
if not t:
|
|
||||||
break
|
remainder = cmdstr
|
||||||
parts.append(t)
|
|
||||||
|
for t, start, end in rex.scanString(cmdstr):
|
||||||
|
|
||||||
|
remainder = cmdstr[end:]
|
||||||
|
parts.append(t[0])
|
||||||
|
|
||||||
|
if remainder != '':
|
||||||
|
parts.append(remainder)
|
||||||
|
|
||||||
if not parts:
|
if not parts:
|
||||||
parts = []
|
parts = []
|
||||||
elif cmdstr.endswith(" "):
|
|
||||||
parts.append("")
|
# First item in parts has always to be the command
|
||||||
|
# so we remove any blank tokens from the start of it
|
||||||
|
while True:
|
||||||
|
if parts and parts[0].strip() == '':
|
||||||
|
del parts[0]
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
parse: typing.List[ParseResult] = []
|
parse: typing.List[ParseResult] = []
|
||||||
params: typing.List[type] = []
|
params: typing.List[type] = []
|
||||||
@ -180,10 +201,15 @@ class CommandManager(mitmproxy.types._CommandBase):
|
|||||||
if parts[i] in self.commands:
|
if parts[i] in self.commands:
|
||||||
params.extend(self.commands[parts[i]].paramtypes)
|
params.extend(self.commands[parts[i]].paramtypes)
|
||||||
elif params:
|
elif params:
|
||||||
typ = params.pop(0)
|
if parts[i].strip() != '':
|
||||||
if typ == mitmproxy.types.Cmd and params and params[0] == mitmproxy.types.Arg:
|
typ = params.pop(0)
|
||||||
if parts[i] in self.commands:
|
if typ == mitmproxy.types.Cmd and params and params[0] == mitmproxy.types.Arg:
|
||||||
params[:] = self.commands[parts[i]].paramtypes
|
if parts[i] in self.commands:
|
||||||
|
params[:] = self.commands[parts[i]].paramtypes
|
||||||
|
else:
|
||||||
|
# If the token is just a bunch of spaces, then we don't
|
||||||
|
# want to count it against the arguments of the command
|
||||||
|
typ = mitmproxy.types.Unknown
|
||||||
else:
|
else:
|
||||||
typ = mitmproxy.types.Unknown
|
typ = mitmproxy.types.Unknown
|
||||||
|
|
||||||
@ -228,6 +254,7 @@ class CommandManager(mitmproxy.types._CommandBase):
|
|||||||
"""
|
"""
|
||||||
if path not in self.commands:
|
if path not in self.commands:
|
||||||
raise exceptions.CommandError("Unknown command: %s" % path)
|
raise exceptions.CommandError("Unknown command: %s" % path)
|
||||||
|
|
||||||
return self.commands[path].call(args)
|
return self.commands[path].call(args)
|
||||||
|
|
||||||
def execute(self, cmdstr: str):
|
def execute(self, cmdstr: str):
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
import io
|
|
||||||
from typing import Union, List
|
|
||||||
|
|
||||||
|
|
||||||
class State(Enum):
|
|
||||||
QUOTE = 1
|
|
||||||
ESCAPE = 2
|
|
||||||
TEXT = 3
|
|
||||||
|
|
||||||
|
|
||||||
class Lexer:
|
|
||||||
|
|
||||||
def __init__(self, text: Union[str, io.StringIO]) -> None:
|
|
||||||
self._count = 0
|
|
||||||
self._parsed = False
|
|
||||||
|
|
||||||
self._state = State.TEXT
|
|
||||||
self._states: List[State] = []
|
|
||||||
self._text_pos = 0
|
|
||||||
self._quote_start_pos = 0
|
|
||||||
|
|
||||||
if isinstance(text, str):
|
|
||||||
self.text = io.StringIO(text)
|
|
||||||
else:
|
|
||||||
self.text = text
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __next__(self):
|
|
||||||
t = self.get_token()
|
|
||||||
|
|
||||||
if t == '':
|
|
||||||
raise StopIteration
|
|
||||||
|
|
||||||
return t
|
|
||||||
|
|
||||||
def get_token(self):
|
|
||||||
try:
|
|
||||||
return self.parse()
|
|
||||||
except ValueError:
|
|
||||||
raise
|
|
||||||
|
|
||||||
def parse(self):
|
|
||||||
acc = ''
|
|
||||||
quote = ''
|
|
||||||
self._state = State.TEXT
|
|
||||||
|
|
||||||
whitespace = "\r\n\t "
|
|
||||||
|
|
||||||
self.text.seek(self._text_pos)
|
|
||||||
|
|
||||||
while True:
|
|
||||||
ch = self.text.read(1)
|
|
||||||
self._text_pos += 1
|
|
||||||
|
|
||||||
# If this is the last char of the string, let's save the token
|
|
||||||
if ch == '' or ch is None:
|
|
||||||
break
|
|
||||||
|
|
||||||
if self._state == State.QUOTE:
|
|
||||||
if ch == '\\':
|
|
||||||
self._states.append(self._state)
|
|
||||||
self._state = State.ESCAPE
|
|
||||||
acc += ch
|
|
||||||
elif ch == quote:
|
|
||||||
self._state = self._states.pop()
|
|
||||||
acc += ch
|
|
||||||
else:
|
|
||||||
acc += ch
|
|
||||||
|
|
||||||
elif self._state == State.ESCAPE:
|
|
||||||
acc += ch
|
|
||||||
self._state = self._states.pop()
|
|
||||||
|
|
||||||
elif self._state == State.TEXT:
|
|
||||||
if ch in whitespace:
|
|
||||||
if acc != '':
|
|
||||||
break
|
|
||||||
elif ch == '"' or ch == "'":
|
|
||||||
quote = ch
|
|
||||||
self._quote_start_pos = self._text_pos
|
|
||||||
self._states.append(self._state)
|
|
||||||
self._state = State.QUOTE
|
|
||||||
acc += ch
|
|
||||||
elif ch == '\\':
|
|
||||||
self._states.append(self._state)
|
|
||||||
self._state = State.ESCAPE
|
|
||||||
acc += ch
|
|
||||||
else:
|
|
||||||
acc += ch
|
|
||||||
|
|
||||||
self._token = acc
|
|
||||||
|
|
||||||
if self._state == State.QUOTE:
|
|
||||||
raise ValueError("No closing quotation for quote in position %d" % self._quote_start_pos)
|
|
||||||
|
|
||||||
return self._token
|
|
@ -52,7 +52,7 @@ CompletionState = typing.NamedTuple(
|
|||||||
class CommandBuffer:
|
class CommandBuffer:
|
||||||
def __init__(self, master: mitmproxy.master.Master, start: str = "") -> None:
|
def __init__(self, master: mitmproxy.master.Master, start: str = "") -> None:
|
||||||
self.master = master
|
self.master = master
|
||||||
self.text = self.flatten(start)
|
self.text = start
|
||||||
# Cursor is always within the range [0:len(buffer)].
|
# Cursor is always within the range [0:len(buffer)].
|
||||||
self._cursor = len(self.text)
|
self._cursor = len(self.text)
|
||||||
self.completion: CompletionState = None
|
self.completion: CompletionState = None
|
||||||
@ -105,7 +105,7 @@ class CommandBuffer:
|
|||||||
ret.append(("commander_invalid", p.value))
|
ret.append(("commander_invalid", p.value))
|
||||||
else:
|
else:
|
||||||
ret.append(("text", ""))
|
ret.append(("text", ""))
|
||||||
ret.append(("text", " "))
|
|
||||||
if remhelp:
|
if remhelp:
|
||||||
ret.append(("text", " "))
|
ret.append(("text", " "))
|
||||||
for v in remhelp:
|
for v in remhelp:
|
||||||
@ -113,11 +113,6 @@ class CommandBuffer:
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def flatten(self, txt):
|
|
||||||
parts, _ = self.parse_quoted(txt)
|
|
||||||
ret = [x.value for x in parts]
|
|
||||||
return " ".join(ret)
|
|
||||||
|
|
||||||
def left(self) -> None:
|
def left(self) -> None:
|
||||||
self.cursor = self.cursor - 1
|
self.cursor = self.cursor - 1
|
||||||
|
|
||||||
@ -141,7 +136,7 @@ class CommandBuffer:
|
|||||||
nxt = self.completion.completer.cycle()
|
nxt = self.completion.completer.cycle()
|
||||||
buf = " ".join([i.value for i in self.completion.parse[:-1]]) + " " + nxt
|
buf = " ".join([i.value for i in self.completion.parse[:-1]]) + " " + nxt
|
||||||
buf = buf.strip()
|
buf = buf.strip()
|
||||||
self.text = self.flatten(buf)
|
self.text = buf
|
||||||
self.cursor = len(self.text)
|
self.cursor = len(self.text)
|
||||||
|
|
||||||
def backspace(self) -> None:
|
def backspace(self) -> None:
|
||||||
@ -155,6 +150,11 @@ class CommandBuffer:
|
|||||||
"""
|
"""
|
||||||
Inserts text at the cursor.
|
Inserts text at the cursor.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# We don't want to insert a space before the command
|
||||||
|
if k == ' ' and self.text[0:self.cursor].strip() == '':
|
||||||
|
return
|
||||||
|
|
||||||
self.text = self.text[:self.cursor] + k + self.text[self.cursor:]
|
self.text = self.text[:self.cursor] + k + self.text[self.cursor:]
|
||||||
self.cursor += len(k)
|
self.cursor += len(k)
|
||||||
self.completion = None
|
self.completion = None
|
||||||
|
@ -115,12 +115,9 @@ class TestCommand:
|
|||||||
[
|
[
|
||||||
"foo bar",
|
"foo bar",
|
||||||
[
|
[
|
||||||
command.ParseResult(
|
command.ParseResult(value = "foo", type = mitmproxy.types.Cmd, valid = False),
|
||||||
value = "foo", type = mitmproxy.types.Cmd, valid = False
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
),
|
command.ParseResult(value = "bar", type = mitmproxy.types.Unknown, valid = False)
|
||||||
command.ParseResult(
|
|
||||||
value = "bar", type = mitmproxy.types.Unknown, valid = False
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
],
|
],
|
||||||
@ -128,6 +125,7 @@ class TestCommand:
|
|||||||
"cmd1 'bar",
|
"cmd1 'bar",
|
||||||
[
|
[
|
||||||
command.ParseResult(value = "cmd1", type = mitmproxy.types.Cmd, valid = True),
|
command.ParseResult(value = "cmd1", type = mitmproxy.types.Cmd, valid = True),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
command.ParseResult(value = "'bar", type = str, valid = True)
|
command.ParseResult(value = "'bar", type = str, valid = True)
|
||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
@ -146,6 +144,7 @@ class TestCommand:
|
|||||||
"cmd3 1",
|
"cmd3 1",
|
||||||
[
|
[
|
||||||
command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd, valid = True),
|
command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd, valid = True),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
command.ParseResult(value = "1", type = int, valid = True),
|
command.ParseResult(value = "1", type = int, valid = True),
|
||||||
],
|
],
|
||||||
[]
|
[]
|
||||||
@ -154,28 +153,27 @@ class TestCommand:
|
|||||||
"cmd3 ",
|
"cmd3 ",
|
||||||
[
|
[
|
||||||
command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd, valid = True),
|
command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd, valid = True),
|
||||||
command.ParseResult(value = "", type = int, valid = False),
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
],
|
],
|
||||||
[]
|
['int']
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"subcommand ",
|
"subcommand ",
|
||||||
[
|
[
|
||||||
command.ParseResult(
|
command.ParseResult(value = "subcommand", type = mitmproxy.types.Cmd, valid = True,),
|
||||||
value = "subcommand", type = mitmproxy.types.Cmd, valid = True,
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
),
|
|
||||||
command.ParseResult(value = "", type = mitmproxy.types.Cmd, valid = False),
|
|
||||||
],
|
],
|
||||||
["arg"],
|
["cmd", "arg"],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"subcommand cmd3 ",
|
"subcommand cmd3 ",
|
||||||
[
|
[
|
||||||
command.ParseResult(value = "subcommand", type = mitmproxy.types.Cmd, valid = True),
|
command.ParseResult(value = "subcommand", type = mitmproxy.types.Cmd, valid = True),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd, valid = True),
|
command.ParseResult(value = "cmd3", type = mitmproxy.types.Cmd, valid = True),
|
||||||
command.ParseResult(value = "", type = int, valid = False),
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
],
|
],
|
||||||
[]
|
["int"]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"cmd4",
|
"cmd4",
|
||||||
@ -188,22 +186,15 @@ class TestCommand:
|
|||||||
"cmd4 ",
|
"cmd4 ",
|
||||||
[
|
[
|
||||||
command.ParseResult(value = "cmd4", type = mitmproxy.types.Cmd, valid = True),
|
command.ParseResult(value = "cmd4", type = mitmproxy.types.Cmd, valid = True),
|
||||||
command.ParseResult(value = "", type = int, valid = False),
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
],
|
],
|
||||||
["str", "path"]
|
["int", "str", "path"]
|
||||||
],
|
|
||||||
[
|
|
||||||
"cmd4 1",
|
|
||||||
[
|
|
||||||
command.ParseResult(value = "cmd4", type = mitmproxy.types.Cmd, valid = True),
|
|
||||||
command.ParseResult(value = "1", type = int, valid = True),
|
|
||||||
],
|
|
||||||
["str", "path"]
|
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"cmd4 1",
|
"cmd4 1",
|
||||||
[
|
[
|
||||||
command.ParseResult(value = "cmd4", type = mitmproxy.types.Cmd, valid = True),
|
command.ParseResult(value = "cmd4", type = mitmproxy.types.Cmd, valid = True),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
command.ParseResult(value = "1", type = int, valid = True),
|
command.ParseResult(value = "1", type = int, valid = True),
|
||||||
],
|
],
|
||||||
["str", "path"]
|
["str", "path"]
|
||||||
@ -219,14 +210,15 @@ class TestCommand:
|
|||||||
"flow ",
|
"flow ",
|
||||||
[
|
[
|
||||||
command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
|
command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
|
||||||
command.ParseResult(value = "", type = flow.Flow, valid = False),
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
],
|
],
|
||||||
["str"]
|
["flow", "str"]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"flow x",
|
"flow x",
|
||||||
[
|
[
|
||||||
command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
|
command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
command.ParseResult(value = "x", type = flow.Flow, valid = False),
|
command.ParseResult(value = "x", type = flow.Flow, valid = False),
|
||||||
],
|
],
|
||||||
["str"]
|
["str"]
|
||||||
@ -235,15 +227,17 @@ class TestCommand:
|
|||||||
"flow x ",
|
"flow x ",
|
||||||
[
|
[
|
||||||
command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
|
command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
command.ParseResult(value = "x", type = flow.Flow, valid = False),
|
command.ParseResult(value = "x", type = flow.Flow, valid = False),
|
||||||
command.ParseResult(value = "", type = str, valid = True),
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
],
|
],
|
||||||
[]
|
["str"]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"flow \"one two",
|
"flow \"one two",
|
||||||
[
|
[
|
||||||
command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
|
command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
command.ParseResult(value = "\"one two", type = flow.Flow, valid = False),
|
command.ParseResult(value = "\"one two", type = flow.Flow, valid = False),
|
||||||
],
|
],
|
||||||
["str"]
|
["str"]
|
||||||
@ -252,11 +246,112 @@ class TestCommand:
|
|||||||
"flow \"three four\"",
|
"flow \"three four\"",
|
||||||
[
|
[
|
||||||
command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
|
command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
command.ParseResult(value = '"three four"', type = flow.Flow, valid = False),
|
command.ParseResult(value = '"three four"', type = flow.Flow, valid = False),
|
||||||
],
|
],
|
||||||
["str"]
|
["str"]
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"spaces ' '",
|
||||||
|
[
|
||||||
|
command.ParseResult(value = "spaces", type = mitmproxy.types.Cmd, valid = False),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
command.ParseResult(value = "' '", type = mitmproxy.types.Unknown, valid = False)
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'spaces2 " "',
|
||||||
|
[
|
||||||
|
command.ParseResult(value = "spaces2", type = mitmproxy.types.Cmd, valid = False),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
command.ParseResult(value = '" "', type = mitmproxy.types.Unknown, valid = False)
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'"abc"',
|
||||||
|
[
|
||||||
|
command.ParseResult(value = '"abc"', type = mitmproxy.types.Cmd, valid = False),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"'def'",
|
||||||
|
[
|
||||||
|
command.ParseResult(value = "'def'", type = mitmproxy.types.Cmd, valid = False),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"cmd10 'a' \"b\" c",
|
||||||
|
[
|
||||||
|
command.ParseResult(value = "cmd10", type = mitmproxy.types.Cmd, valid = False),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
command.ParseResult(value = "'a'", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
command.ParseResult(value = '"b"', type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
command.ParseResult(value = "c", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"cmd11 'a \"b\" c'",
|
||||||
|
[
|
||||||
|
command.ParseResult(value = "cmd11", type = mitmproxy.types.Cmd, valid = False),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
command.ParseResult(value = "'a \"b\" c'", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'cmd12 "a \'b\' c"',
|
||||||
|
[
|
||||||
|
command.ParseResult(value = "cmd12", type = mitmproxy.types.Cmd, valid = False),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
command.ParseResult(value = '"a \'b\' c"', type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
r'cmd13 "a \"b\" c"',
|
||||||
|
[
|
||||||
|
command.ParseResult(value = "cmd13", type = mitmproxy.types.Cmd, valid = False),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
command.ParseResult(value = r'"a \"b\" c"', type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
r"cmd14 'a \'b\' c'",
|
||||||
|
[
|
||||||
|
command.ParseResult(value = "cmd14", type = mitmproxy.types.Cmd, valid = False),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
command.ParseResult(value = r"'a \'b\' c'", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
" spaces_at_the_begining_are_stripped",
|
||||||
|
[
|
||||||
|
command.ParseResult(value = "spaces_at_the_begining_are_stripped", type = mitmproxy.types.Cmd, valid = False),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
" spaces_at_the_begining_are_stripped but_not_at_the_end ",
|
||||||
|
[
|
||||||
|
command.ParseResult(value = "spaces_at_the_begining_are_stripped", type = mitmproxy.types.Cmd, valid = False),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
command.ParseResult(value = "but_not_at_the_end", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
command.ParseResult(value = " ", type = mitmproxy.types.Unknown, valid = False),
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
with taddons.context() as tctx:
|
with taddons.context() as tctx:
|
||||||
tctx.master.addons.add(TAddon())
|
tctx.master.addons.add(TAddon())
|
||||||
for s, expected, expectedremain in tests:
|
for s, expected, expectedremain in tests:
|
||||||
|
@ -1,75 +0,0 @@
|
|||||||
from mitmproxy import lexer
|
|
||||||
import pytest
|
|
||||||
import io
|
|
||||||
|
|
||||||
|
|
||||||
class TestScripts:
|
|
||||||
|
|
||||||
def test_simple(self):
|
|
||||||
|
|
||||||
cases = [
|
|
||||||
{
|
|
||||||
"text": r'abc',
|
|
||||||
"result": ['abc']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": r'"Hello \" Double Quotes"',
|
|
||||||
"result": ['"Hello \\" Double Quotes"']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": r"'Hello \' Single Quotes'",
|
|
||||||
"result": ["'Hello \\' Single Quotes'"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": r'"\""',
|
|
||||||
"result": ['"\\""']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": r'abc "def\" \x bla \z \\ \e \ " xpto',
|
|
||||||
"result": ['abc', '"def\\" \\x bla \\z \\\\ \\e \\ "', 'xpto']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": r'',
|
|
||||||
"result": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": r' ',
|
|
||||||
"result": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": r' ',
|
|
||||||
"result": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": r'Space in the end ',
|
|
||||||
"result": ['Space', 'in', 'the', 'end']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": '\n\n\rHello\n World With Spaces\n\n',
|
|
||||||
"result": ['Hello', 'World', 'With', 'Spaces']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": r'\" Escaping characters without reason',
|
|
||||||
"result": ['\\"', 'Escaping', 'characters', 'without', 'reason']
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
for t in cases:
|
|
||||||
|
|
||||||
lex = lexer.Lexer(t['text'])
|
|
||||||
tokens = list(lex)
|
|
||||||
result = t['result']
|
|
||||||
assert(tokens == result)
|
|
||||||
|
|
||||||
def test_fail(self):
|
|
||||||
text = r'"should fail with missing closing quote'
|
|
||||||
lex = lexer.Lexer(text)
|
|
||||||
with pytest.raises(ValueError, match="No closing quotation"):
|
|
||||||
assert list(lex)
|
|
||||||
|
|
||||||
def test_stringio_text(self):
|
|
||||||
text = io.StringIO(r'Increase test coverage')
|
|
||||||
lex = lexer.Lexer(text)
|
|
||||||
tokens = list(lex)
|
|
||||||
result = ['Increase', 'test', 'coverage']
|
|
||||||
assert(tokens == result)
|
|
@ -165,8 +165,3 @@ class TestCommandBuffer:
|
|||||||
cb = commander.CommandBuffer(tctx.master)
|
cb = commander.CommandBuffer(tctx.master)
|
||||||
cb.text = "foo"
|
cb.text = "foo"
|
||||||
assert cb.render()
|
assert cb.render()
|
||||||
|
|
||||||
def test_flatten(self):
|
|
||||||
with taddons.context() as tctx:
|
|
||||||
cb = commander.CommandBuffer(tctx.master)
|
|
||||||
assert cb.flatten("foo bar") == "foo bar"
|
|
||||||
|
@ -3,12 +3,14 @@ from mitmproxy.tools.console import defaultkeys
|
|||||||
from mitmproxy.tools.console import keymap
|
from mitmproxy.tools.console import keymap
|
||||||
from mitmproxy.tools.console import master
|
from mitmproxy.tools.console import master
|
||||||
from mitmproxy import command
|
from mitmproxy import command
|
||||||
|
from mitmproxy import ctx
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_commands_exist():
|
async def test_commands_exist():
|
||||||
|
command_manager = command.CommandManager(ctx)
|
||||||
|
|
||||||
km = keymap.Keymap(None)
|
km = keymap.Keymap(None)
|
||||||
defaultkeys.map(km)
|
defaultkeys.map(km)
|
||||||
assert km.bindings
|
assert km.bindings
|
||||||
@ -16,7 +18,10 @@ async def test_commands_exist():
|
|||||||
await m.load_flow(tflow())
|
await m.load_flow(tflow())
|
||||||
|
|
||||||
for binding in km.bindings:
|
for binding in km.bindings:
|
||||||
cmd, *args = command.get_lexer(binding.command)
|
results = command_manager.parse_partial(binding.command)
|
||||||
|
|
||||||
|
cmd = results[0][0].value
|
||||||
|
args = [a.value for a in results[0][1:]]
|
||||||
|
|
||||||
assert cmd in m.commands.commands
|
assert cmd in m.commands.commands
|
||||||
|
|
||||||
@ -24,4 +29,7 @@ async def test_commands_exist():
|
|||||||
try:
|
try:
|
||||||
cmd_obj.prepare_args(args)
|
cmd_obj.prepare_args(args)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
||||||
|
import pdb
|
||||||
|
pdb.set_trace()
|
||||||
raise ValueError("Invalid command: {}".format(binding.command)) from e
|
raise ValueError("Invalid command: {}".format(binding.command)) from e
|
||||||
|
Loading…
Reference in New Issue
Block a user