Skip to content

Commit

Permalink
Another fix for unescaped double quotes
Browse files Browse the repository at this point in the history
  • Loading branch information
otsch committed Nov 20, 2024
1 parent e2ed0ec commit 89d58f4
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.1.2] - 2024-11-20
### Fixed
- Another improvement for parsing invalid JSON with unescaped double quote characters inside string values.

## [1.1.1] - 2024-11-20
### Fixed
- Improve parsing invalid JSON by detecting and fixing unescaped double quote characters inside string values.
Expand Down
20 changes: 12 additions & 8 deletions src/Json.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,18 @@ function ($match) {
) ?? $jsonString;

// If JSON string contains unescaped double quotes inside a string value, try to fix it.
if (preg_match('/".+?": "(.+(?<!\\\\)".+)"\s*?(,|})/', $jsonString)) {
$jsonString = preg_replace_callback('/".+?": "(.+(?<!\\\\)".+)"\s*?(,|})/', function ($match) {
return str_replace(
$match[1],
str_replace('"', '\"', $match[1]),
$match[0],
);
}, $jsonString) ?? $jsonString;
if (preg_match('/"[^",}]*?":\s*?"((?:[^",}]*?(?<!\\\\)")+[^"]*?)"\s*?(,|})/', $jsonString)) {
$jsonString = preg_replace_callback(
'/"[^",}]*?":\s*?"((?:[^",}]*?(?<!\\\\)")+[^"]*?)"\s*?(,|})/',
function ($match) {
return str_replace(
$match[1],
str_replace('"', '\"', $match[1]),
$match[0],
);
},
$jsonString,
) ?? $jsonString;
}

return $jsonString;
Expand Down
12 changes: 12 additions & 0 deletions tests/JsonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,18 @@
]);
});

it('correctly fixes unescaped double quotes inside a string value in one-line JSON', function () {
$jsonString = <<<JSON
{ "foo": "bar", "description": "lorem "ipsum" asdf", "baz": "quz "yo" "" "lo"" }
JSON;

expect(Json::stringToArray($jsonString))->toBe([
'foo' => 'bar',
'description' => 'lorem "ipsum" asdf',
'baz' => 'quz "yo" "" "lo"',
]);
});

it('throws an exception when the string is not a (valid) JSON string', function () {
Json::stringToArray('{ foo: bar ]');
})->throws(InvalidJsonException::class);

0 comments on commit 89d58f4

Please sign in to comment.