Skip to content

Commit

Permalink
unescape quotes when inserting json (#95)
Browse files Browse the repository at this point in the history
Co-authored-by: Kevin Tabb <[email protected]>
  • Loading branch information
K128kevin and Kevin Tabb authored Feb 13, 2023
1 parent a32bc1d commit d5f9391
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
6 changes: 5 additions & 1 deletion src/DataIntegrity.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,17 @@ public static function ensureFieldsPresent(dict<string, mixed> $row, table_schem
if ($row[$field_name] is nonnull) {
if (!Str\is_empty((string)$row[$field_name])) {
// validate json string
$json_obj = \json_decode((string)$row[$field_name]);
// json_decode will return null if json string contains escaped quotes - mysql just unescapes the quotes and accepts the string
$json_string = \stripslashes((string)$row[$field_name]);
$json_obj = \json_decode($json_string);
if ($json_obj is null) {
// invalid json
throw new SQLFakeRuntimeException(
"Invalid value '{$field_value}' for column '{$field_name}' on '{$schema['name']}', expected json",
);
}
// mysql removes the \
$row[$field_name] = $json_string;
} else {
// empty strings are not valid for json columns
throw new SQLFakeRuntimeException(
Expand Down
10 changes: 9 additions & 1 deletion tests/InsertQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,19 @@ final class InsertQueryTest extends HackTest {
public async function testValidJsonInsertIntoJsonColumn(): Awaitable<void> {
$conn = static::$conn as nonnull;
QueryContext::$strictSQLMode = true;
await $conn->query("INSERT INTO table_with_json (id, data) VALUES (1, '{\"test\":123}')");
await $conn->query('INSERT INTO table_with_json (id, data) VALUES (1, \'{"test":123}\')');
$result = await $conn->query('SELECT * FROM table_with_json');
expect($result->rows())->toBeSame(vec[dict['id' => 1, 'data' => '{"test":123}']]);
}

public async function testValidJsonWithQuotesEscapedInsertIntoJsonColumn(): Awaitable<void> {
$conn = static::$conn as nonnull;
QueryContext::$strictSQLMode = true;
await $conn->query('INSERT INTO table_with_json (id, data) VALUES (1, \'{\\\"domains\\\":[\\\"foo.com\\\"]}\')');
$result = await $conn->query('SELECT * FROM table_with_json');
expect($result->rows())->toBeSame(vec[dict['id' => 1, 'data' => '{"domains":["foo.com"]}']]);
}

public async function testDupeInsertNoConflicts(): Awaitable<void> {
$conn = static::$conn as nonnull;
await $conn->query(
Expand Down

0 comments on commit d5f9391

Please sign in to comment.