Skip to content

Instantly share code, notes, and snippets.

@nijave
Last active April 24, 2023 18:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nijave/ef7ed52d17089c37282d20a284cfde57 to your computer and use it in GitHub Desktop.
Save nijave/ef7ed52d17089c37282d20a284cfde57 to your computer and use it in GitHub Desktop.
Makes json parseable if the end got lopped off
def fix_truncated_json(err_json: str) -> str:
"""closes open delimiters so json is parseable"""
stack = []
expect_literal = False
last_literal = []
for i, c in enumerate(err_json):
if c == '"':
if i > 0 and err_json[i-1] == '\\':
continue
if stack[-1] == '"':
stack.pop()
else:
stack.append('"')
if c in ('{', '['):
stack.append(c)
if c in ('}', ']'):
stack.pop()
if c in (",", "{", "}", "[", "]") and expect_literal:
expect_literal = False
last_literal.clear()
if expect_literal and c != " ":
last_literal.append(c)
if c == ":" and stack[-1] != '"':
expect_literal = True
trailer = []
for token in stack[::-1]:
if token == '"':
trailer.append('"')
if token == '{':
trailer.append('}')
if token == '[':
trailer.append(']')
if last_literal:
if last_literal[0] == 't' and len(last_literal) < 4:
trailer.insert(0, "true"[len(last_literal):])
if last_literal[0] == 'f' and len(last_literal) < 5:
trailer.insert(0, "false"[len(last_literal):])
if last_literal[0].isdigit():
trailer.insert(0, " null")
err_json = err_json[:-1-len(last_literal)]
trailer.insert(0, err_json)
return "".join(trailer)
for test_str in (
'{"a": {"b": 1234',
'{"a": {"b": t',
'{"a": {"b": tr',
'{"a": {"b": tru',
'{"a": {"b": true',
'{"a": {"b": true ',
'{"a": {"b": fa',
'{"a": {"b": ["abc',
'{"a": {"b": ["abc", "a',
):
print("t", test_str)
try:
j = orjson.loads(test_str)
except orjson.JSONDecodeError:
fixed = fix_truncated_json(test_str)
print("f", fixed)
j = orjson.loads(
fixed
)
print("o", j)
print()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment