Skip to content

Commit

Permalink
fix: jsonMerge with complex json literals
Browse files Browse the repository at this point in the history
  • Loading branch information
cyjake committed Jan 9, 2025
1 parent 4840937 commit 93d6f8a
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/bone.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const deepEqual = require('deep-equal');
const debug = require('debug')('leoric');
const pluralize = require('pluralize');
const { executeValidator, LeoricValidateError } = require('./validator');
const SqlString = require('sqlstring');
require('reflect-metadata');

const { default: DataTypes } = require('./data_types');
Expand Down Expand Up @@ -1580,7 +1581,7 @@ class Bone {
const method = preserve ? 'JSON_MERGE_PRESERVE' : 'JSON_MERGE_PATCH';
const data = { ...values };
for (const [name, value] of Object.entries(values)) {
data[name] = new Raw(`${method}(${name}, '${JSON.stringify(value).replace(/'/g, "\\'")}')`);
data[name] = new Raw(`${method}(${name}, ${SqlString.escape(JSON.stringify(value))})`);
}
return this.update(conditions, data, restOptions);
}
Expand Down
10 changes: 8 additions & 2 deletions src/expr.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,16 @@ function parseExprList(str, ...values) {

function string() {
let value = '';
let escaped = false;
const quote = chr;
next();
while (chr && chr !== quote) {
value += chr;
while (chr && (chr !== quote || escaped)) {
if (chr === '\\' && !escaped) {
escaped = true;
} else {
value += chr;
escaped = false;
}
next();
}
if (chr !== quote) {
Expand Down
13 changes: 13 additions & 0 deletions test/integration/suite/json.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ describe('=> Basic', () => {
assert.equal(gen2.extra.url, 'https://www.wanxiang.art/?foo=');
});

it('bone.jsonMerge(name, values, options) should escape double quotations', async () => {
const gen = await Gen.create({ name: '章3️⃣疯', extra: {} });
await gen.jsonMerge('extra', { a: `fo'o"quote"bar` });
assert.equal(gen.extra.a, `fo'o"quote"bar`);
});

it('bone.update(values, options) with JSON_MERGE_PATCH func should work', async () => {
const gen = await Gen.create({ name: 'testUpdateGen', extra: { test: 'gen' }});
assert.equal(gen.extra.test, 'gen');
Expand Down Expand Up @@ -83,6 +89,13 @@ describe('=> Basic', () => {
assert.equal(gen.extra.a, 'foo\'bar');
});

it('Bone.jsonMerge(conditions, values, options) should escape double quotations', async () => {
const gen = await Gen.create({ name: '章3️⃣疯', extra: {} });
await Gen.jsonMerge({ id: gen.id }, { extra: { a: 'foo"quote"bar' } });
await gen.reload();
assert.equal(gen.extra.a, 'foo"quote"bar');
});

it('Bone.jsonMergePreserve(conditions, values, options) should work', async () => {
const gen = await Gen.create({ name: '章3️⃣疯', extra: {} });
await Gen.jsonMerge({ id: gen.id }, { extra: { a: 3 } });
Expand Down
1 change: 1 addition & 0 deletions test/unit/expr.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ describe('=> parse literals', function() {
assert.deepEqual(parseExpr("'b'"), { type: 'literal', value: 'b' });
// incomplete literal
assert.throws(() => parseExpr("'a"), 'Unexpected end of string');
assert.deepEqual(parseExpr('"a\'b\\"c"'), { type: 'literal', value: `a'b"c` });
});

it('parse number[]', function() {
Expand Down

0 comments on commit 93d6f8a

Please sign in to comment.