json-repair 0.29.5__tar.gz → 0.29.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {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
|