json-repair 0.29.5__tar.gz → 0.29.7__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {json_repair-0.29.5/src/json_repair.egg-info → json_repair-0.29.7}/PKG-INFO +1 -1
- {json_repair-0.29.5 → json_repair-0.29.7}/pyproject.toml +1 -1
- {json_repair-0.29.5 → json_repair-0.29.7}/src/json_repair/json_parser.py +20 -20
- {json_repair-0.29.5 → json_repair-0.29.7/src/json_repair.egg-info}/PKG-INFO +1 -1
- {json_repair-0.29.5 → json_repair-0.29.7}/tests/test_json_repair.py +2 -1
- {json_repair-0.29.5 → json_repair-0.29.7}/LICENSE +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/README.md +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/setup.cfg +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/src/json_repair/__init__.py +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/src/json_repair/__main__.py +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/src/json_repair/json_context.py +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/src/json_repair/json_repair.py +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/src/json_repair/py.typed +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/src/json_repair/string_file_wrapper.py +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/src/json_repair.egg-info/SOURCES.txt +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/src/json_repair.egg-info/dependency_links.txt +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/src/json_repair.egg-info/entry_points.txt +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/src/json_repair.egg-info/top_level.txt +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/tests/test_coverage.py +0 -0
- {json_repair-0.29.5 → json_repair-0.29.7}/tests/test_performance.py +0 -0
@@ -3,7 +3,7 @@ requires = ["setuptools>=61.0"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
4
4
|
[project]
|
5
5
|
name = "json_repair"
|
6
|
-
version = "0.29.
|
6
|
+
version = "0.29.7"
|
7
7
|
license = {file = "LICENSE"}
|
8
8
|
authors = [
|
9
9
|
{ name="Stefano Baccianella", email="4247706+mangiucugna@users.noreply.github.com" },
|
@@ -308,9 +308,6 @@ class JSONParser:
|
|
308
308
|
rstring_delimiter_missing = True
|
309
309
|
# check if this is a case in which the closing comma is NOT missing instead
|
310
310
|
i = self.skip_to_character(character=rstring_delimiter, idx=1)
|
311
|
-
# If the rstring_delimeter is escaped then it's not what we are looking for
|
312
|
-
while self.get_char_at(i - 1) == "\\":
|
313
|
-
i = self.skip_to_character(character=rstring_delimiter, idx=i + 1)
|
314
311
|
next_c = self.get_char_at(i)
|
315
312
|
if next_c:
|
316
313
|
i += 1
|
@@ -319,6 +316,15 @@ class JSONParser:
|
|
319
316
|
next_c = self.get_char_at(i)
|
320
317
|
if next_c and next_c in [",", "}"]:
|
321
318
|
rstring_delimiter_missing = False
|
319
|
+
elif char == ",":
|
320
|
+
# We couldn't find any rstring_delimeter before the end of the string
|
321
|
+
# check if this is the last string of an object and therefore we can keep going
|
322
|
+
# make an exception if this is the last char before the closing brace
|
323
|
+
i = self.skip_to_character(character="}", idx=1)
|
324
|
+
if i > 1:
|
325
|
+
# Ok it's not right after the comma
|
326
|
+
# Let's ignore
|
327
|
+
rstring_delimiter_missing = False
|
322
328
|
if rstring_delimiter_missing:
|
323
329
|
self.log(
|
324
330
|
"While parsing a string missing the left delimiter in object value context, we found a , or } and we couldn't determine that a right delimiter was present. Stopping here",
|
@@ -330,8 +336,8 @@ class JSONParser:
|
|
330
336
|
if char and len(string_acc) > 0 and string_acc[-1] == "\\":
|
331
337
|
# This is a special case, if people use real strings this might happen
|
332
338
|
self.log("Found a stray escape sequence, normalizing it")
|
333
|
-
string_acc = string_acc[:-1]
|
334
339
|
if char in [rstring_delimiter, "t", "n", "r", "b", "\\"]:
|
340
|
+
string_acc = string_acc[:-1]
|
335
341
|
escape_seqs = {"t": "\t", "n": "\n", "r": "\r", "b": "\b"}
|
336
342
|
string_acc += escape_seqs.get(char, char) or char
|
337
343
|
self.index += 1
|
@@ -414,11 +420,6 @@ class JSONParser:
|
|
414
420
|
):
|
415
421
|
i += 1
|
416
422
|
i = self.skip_to_character(character=rstring_delimiter, idx=i)
|
417
|
-
# If the rstring_delimeter is escaped then it's not what we are looking for
|
418
|
-
while self.get_char_at(i - 1) == "\\":
|
419
|
-
i = self.skip_to_character(
|
420
|
-
character=rstring_delimiter, idx=i + 1
|
421
|
-
)
|
422
423
|
next_c = self.get_char_at(i)
|
423
424
|
# Ok now I found a delimiter, let's skip whitespaces and see if next we find a }
|
424
425
|
i += 1
|
@@ -432,7 +433,9 @@ class JSONParser:
|
|
432
433
|
string_acc += str(char)
|
433
434
|
self.index += 1
|
434
435
|
char = self.get_char_at()
|
435
|
-
elif
|
436
|
+
elif (
|
437
|
+
next_c == rstring_delimiter and self.get_char_at(i - 1) != "\\"
|
438
|
+
):
|
436
439
|
if self.context.current == ContextValues.OBJECT_VALUE:
|
437
440
|
# But this might not be it! This could be just a missing comma
|
438
441
|
# We found a delimiter and we need to check if this is a key
|
@@ -441,19 +444,13 @@ class JSONParser:
|
|
441
444
|
i = self.skip_to_character(
|
442
445
|
character=rstring_delimiter, idx=i
|
443
446
|
)
|
444
|
-
# If the rstring_delimeter is escaped then it's not what we are looking for
|
445
|
-
while self.get_char_at(i - 1) == "\\":
|
446
|
-
i = self.skip_to_character(
|
447
|
-
character=rstring_delimiter, idx=i + 1
|
448
|
-
)
|
449
447
|
i += 1
|
450
448
|
next_c = self.get_char_at(i)
|
451
449
|
while next_c and next_c != ":":
|
452
|
-
if next_c
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
]:
|
450
|
+
if next_c == "," or (
|
451
|
+
next_c == rstring_delimiter
|
452
|
+
and self.get_char_at(i - 1) != "\\"
|
453
|
+
):
|
457
454
|
break
|
458
455
|
i += 1
|
459
456
|
next_c = self.get_char_at(i)
|
@@ -582,6 +579,9 @@ class JSONParser:
|
|
582
579
|
char = self.json_str[self.index + idx]
|
583
580
|
except IndexError:
|
584
581
|
return idx
|
582
|
+
if self.index + idx > 0 and self.json_str[self.index + idx - 1] == "\\":
|
583
|
+
# Ah this is an escaped character, try again
|
584
|
+
return self.skip_to_character(character=character, idx=idx + 1)
|
585
585
|
return idx
|
586
586
|
|
587
587
|
def _log(self, text: str) -> None:
|
@@ -120,7 +120,7 @@ def test_array_edge_cases():
|
|
120
120
|
|
121
121
|
def test_escaping():
|
122
122
|
assert repair_json("'\"'") == '""'
|
123
|
-
assert repair_json("{\"key\": 'string\"\n\t\le'") == '{"key": "string\\"\\n\\
|
123
|
+
assert repair_json("{\"key\": 'string\"\n\t\le'") == '{"key": "string\\"\\n\\t\\\\le"}'
|
124
124
|
assert repair_json(r'{"real_content": "Some string: Some other string \t Some string <a href=\"https://domain.com\">Some link</a>"') == r'{"real_content": "Some string: Some other string \t Some string <a href=\"https://domain.com\">Some link</a>"}'
|
125
125
|
assert repair_json('{"key_1\n": "value"}') == '{"key_1": "value"}'
|
126
126
|
assert repair_json('{"key\t_": "value"}') == '{"key\\t_": "value"}'
|
@@ -140,6 +140,7 @@ def test_object_edge_cases():
|
|
140
140
|
assert repair_json('{"key": "Lorem "ipsum" s,"}') == '{"key": "Lorem \\"ipsum\\" s,"}'
|
141
141
|
assert repair_json('{"lorem": ipsum, sic, datum.",}') == '{"lorem": "ipsum, sic, datum."}'
|
142
142
|
assert repair_json('{"lorem": sic tamet. "ipsum": sic tamet, quick brown fox. "sic": ipsum}') == '{"lorem": "sic tamet.", "ipsum": "sic tamet", "sic": "ipsum"}'
|
143
|
+
assert repair_json('{"lorem_ipsum": "sic tamet, quick brown fox. }') == '{"lorem_ipsum": "sic tamet, quick brown fox."}'
|
143
144
|
assert repair_json('{"key":value, " key2":"value2" }') == '{"key": "value", " key2": "value2"}'
|
144
145
|
assert repair_json('{"key":value "key2":"value2" }') == '{"key": "value", "key2": "value2"}'
|
145
146
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|