diff --git a/httpie/cli/nested_json.py b/httpie/cli/nested_json.py index 807076c0..615f0427 100644 --- a/httpie/cli/nested_json.py +++ b/httpie/cli/nested_json.py @@ -61,7 +61,19 @@ class Token(NamedTuple): def assert_cant_happen() -> NoReturn: - raise ValueError("Unexpected value") + raise ValueError('Unexpected value') + + +def check_escaped_int(value: str) -> str: + if not value.startswith('\\'): + raise ValueError('Not an escaped int') + + try: + int(value[1:]) + except ValueError as exc: + raise ValueError('Not an escaped int') from exc + else: + return value[1:] def tokenize(source: str) -> Iterator[Token]: @@ -75,12 +87,18 @@ def tokenize(source: str) -> Iterator[Token]: return None value = ''.join(buffer) - try: - value = int(value) - except ValueError: - kind = TokenKind.TEXT + for variation, kind in [ + (int, TokenKind.NUMBER), + (check_escaped_int, TokenKind.TEXT), + ]: + try: + value = variation(value) + except ValueError: + continue + else: + break else: - kind = TokenKind.NUMBER + kind = TokenKind.TEXT yield Token( kind, value, start=cursor - (len(buffer) + backslashes), end=cursor diff --git a/tests/test_json.py b/tests/test_json.py index 287b2f41..ae748340 100644 --- a/tests/test_json.py +++ b/tests/test_json.py @@ -376,6 +376,28 @@ def test_complex_json_arguments_with_non_json(httpbin, request_type, value): 'people': {'known_ids': [None, 1000, None, None, None, 5000]}, }, ), + ( + [ + r'foo[\1][type]=migration', + r'foo[\2][type]=migration', + r'foo[\dates]:=[2012, 2013]', + r'foo[\dates][0]:=2014', + r'foo[\2012 bleh]:=2013', + r'foo[bleh \2012]:=2014', + r'\2012[x]:=2', + r'\2012[\[3\]]:=4', + ], + { + 'foo': { + '1': {'type': 'migration'}, + '2': {'type': 'migration'}, + '\\dates': [2014, 2013], + '\\2012 bleh': 2013, + 'bleh \\2012': 2014, + }, + '2012': {'x': 2, '[3]': 4}, + }, + ), ], ) def test_nested_json_syntax(input_json, expected_json, httpbin): @@ -465,6 +487,14 @@ def test_nested_json_syntax(input_json, expected_json, httpbin): ['foo[-10]:=[1,2]'], 'HTTPie Value Error: Negative indexes are not supported.\nfoo[-10]\n ^^^', ), + ( + ['foo[0]:=1', 'foo[]:=2', 'foo[\\2]:=3'], + "HTTPie Type Error: Can't perform 'key' based access on 'foo' which has a type of 'array' but this operation requires a type of 'object'.\nfoo[\\2]\n ^^^^", + ), + ( + ['foo[\\1]:=2', 'foo[5]:=3'], + "HTTPie Type Error: Can't perform 'index' based access on 'foo' which has a type of 'object' but this operation requires a type of 'array'.\nfoo[5]\n ^^^", + ), ], ) def test_nested_json_errors(input_json, expected_error, httpbin):