Skip to content

Commit 8eee599

Browse files
committed
Fix #154, sometimes when repairing a confusing delimiter the poor closing brace was involved. Try not do that anymore
1 parent 48e8e2e commit 8eee599

File tree

6 files changed

+18
-7
lines changed

6 files changed

+18
-7
lines changed

.github/workflows/python-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
fail-fast: false
1818
matrix:
1919
# https://github.com/actions/python-versions/blob/main/versions-manifest.json
20-
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14.0-rc.2"]
20+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
2121

2222
steps:
2323
- uses: actions/checkout@v5

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ repos:
88
pass_filenames: false
99
- repo: https://github.com/astral-sh/ruff-pre-commit
1010
# Ruff version.
11-
rev: v0.13.3
11+
rev: v0.14.1
1212
hooks:
1313
# Run the linter.
1414
- id: ruff-check
@@ -38,7 +38,7 @@ repos:
3838
pass_filenames: false
3939
types: [python]
4040
- repo: https://github.com/semgrep/pre-commit
41-
rev: "v1.139.0"
41+
rev: "v1.140.0"
4242
hooks:
4343
- id: semgrep
4444
args:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ requires = ["setuptools>=61.0"]
33
build-backend = "setuptools.build_meta"
44
[project]
55
name = "json_repair"
6-
version = "0.52.0"
6+
version = "0.52.1"
77
license = "MIT"
88
license-files = ["LICENSE"]
99
authors = [

src/json_repair/json_parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ def skip_whitespaces_at(self, idx: int = 0, move_main_index=True) -> int:
155155
return idx
156156
return idx
157157

158-
def skip_to_character(self, character: str | list, idx: int = 0) -> int:
158+
def skip_to_character(self, character: str | list[str], idx: int = 0) -> int:
159159
"""
160160
This function quickly iterates to find a character, syntactic sugar to make the code more concise
161161
"""

src/json_repair/parse_string.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from typing import TYPE_CHECKING
22

3-
from .constants import STRING_DELIMITERS
3+
from .constants import STRING_DELIMITERS, JSONReturnType
44
from .json_context import ContextValues
55

66
if TYPE_CHECKING:
77
from .json_parser import JSONParser
88

99

10-
def parse_string(self: "JSONParser") -> str | bool | None:
10+
def parse_string(self: "JSONParser") -> JSONReturnType:
1111
# <string> is a string of valid characters enclosed in quotes
1212
# i.e. { name: "John" }
1313
# Somehow all weird cases in an invalid JSON happen to be resolved in this function, so be careful here
@@ -201,6 +201,16 @@ def parse_string(self: "JSONParser") -> str | bool | None:
201201
if not self.get_char_at(i):
202202
# No delimiter found
203203
break
204+
if self.context.current == ContextValues.OBJECT_VALUE and char == "}":
205+
# We found the end of an object while parsing a value
206+
# Check if the object is really over, to avoid doubling the closing brace
207+
i = self.skip_whitespaces_at(idx=1, move_main_index=False)
208+
next_c = self.get_char_at(i)
209+
if not next_c:
210+
self.log(
211+
"While parsing a string in object value context, we found a } that closes the object, stopping here",
212+
)
213+
break
204214
string_acc += char
205215
self.index += 1
206216
char = self.get_char_at()

tests/test_parse_object.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def test_parse_object():
2323
def test_parse_object_edge_cases():
2424
assert repair_json("{foo: [}") == '{"foo": []}'
2525
assert repair_json('{"": "value"') == '{"": "value"}'
26+
assert repair_json('{"key": "v"alue"}') == '{"key": "v\\"alue\\""}'
2627
assert repair_json('{"value_1": true, COMMENT "value_2": "data"}') == '{"value_1": true, "value_2": "data"}'
2728
assert (
2829
repair_json('{"value_1": true, SHOULD_NOT_EXIST "value_2": "data" AAAA }')

0 commit comments

Comments
 (0)