aboutsummaryrefslogtreecommitdiffstats
path: root/mitmproxy/command_lexer.py
blob: f042f3c951181ace3716f9b366cf34727bae8675 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import ast
import re

import pyparsing

# TODO: There is a lot of work to be done here.
# The current implementation is written in a way that _any_ input is valid,
# which does not make sense once things get more complex.

PartialQuotedString = pyparsing.Regex(
    re.compile(
        r'''
            (["'])  # start quote
            (?:
                (?!\1)[^\\]  # unescaped character that is not our quote nor the begin of an escape sequence. We can't use \1 in []
                |
                (?:\\.)  # escape sequence
            )*
            (?:\1|$)  # end quote
        ''',
        re.VERBOSE
    )
)

expr = pyparsing.ZeroOrMore(
    PartialQuotedString
    | pyparsing.Word(" \r\n\t")
    | pyparsing.CharsNotIn("""'" \r\n\t""")
).leaveWhitespace()


def quote(val: str) -> str:
    if val and all(char not in val for char in "'\" \r\n\t"):
        return val
    return repr(val)  # TODO: More of a hack.


def unquote(x: str) -> str:
    quoted = (
            (x.startswith('"') and x.endswith('"'))
            or
            (x.startswith("'") and x.endswith("'"))
    )
    if quoted:
        try:
            x = ast.literal_eval(x)
        except Exception:
            x = x[1:-1]
    return x