Skip to content

Commit 95208e9

Browse files
authored
Postgres: Safely escape strings in nested objects (#5855)
* Postgres: Safely handle string in nested objects * fix failing tests
1 parent 4f21c36 commit 95208e9

File tree

2 files changed

+24
-16
lines changed

2 files changed

+24
-16
lines changed

spec/ParseQuery.spec.js

+18
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,24 @@ describe('Parse.Query testing', () => {
359359
}, done.fail);
360360
});
361361

362+
it('nested equalTo string with single quote', async () => {
363+
const obj = new TestObject({ nested: { foo: "single'quote" } });
364+
await obj.save();
365+
const query = new Parse.Query(TestObject);
366+
query.equalTo('nested.foo', "single'quote");
367+
const result = await query.get(obj.id);
368+
equal(result.get('nested').foo, "single'quote");
369+
});
370+
371+
it('nested containedIn string with single quote', async () => {
372+
const obj = new TestObject({ nested: { foo: ["single'quote"]} });
373+
await obj.save();
374+
const query = new Parse.Query(TestObject);
375+
query.containedIn('nested.foo', ["single'quote"]);
376+
const result = await query.get(obj.id);
377+
equal(result.get('nested').foo[0], "single'quote");
378+
});
379+
362380
it('nested containedIn string', done => {
363381
const sender1 = { group: ['A', 'B'] };
364382
const sender2 = { group: ['A', 'C'] };

src/Adapters/Storage/Postgres/PostgresStorageAdapter.js

+6-16
Original file line numberDiff line numberDiff line change
@@ -282,26 +282,16 @@ const buildWhereClause = ({ schema, query, index }): WhereClause => {
282282
patterns.push(`${name} IS NULL`);
283283
} else {
284284
if (fieldValue.$in) {
285-
const inPatterns = [];
286285
name = transformDotFieldToComponents(fieldName).join('->');
287-
fieldValue.$in.forEach(listElem => {
288-
if (typeof listElem === 'string') {
289-
if (listElem.includes('"') || listElem.includes("'")) {
290-
throw new Parse.Error(
291-
Parse.Error.INVALID_JSON,
292-
'bad $in value; Strings with quotes cannot yet be safely escaped'
293-
);
294-
}
295-
inPatterns.push(`"${listElem}"`);
296-
} else {
297-
inPatterns.push(`${listElem}`);
298-
}
299-
});
300-
patterns.push(`(${name})::jsonb @> '[${inPatterns.join()}]'::jsonb`);
286+
patterns.push(`($${index}:raw)::jsonb @> $${index + 1}::jsonb`);
287+
values.push(name, JSON.stringify(fieldValue.$in));
288+
index += 2;
301289
} else if (fieldValue.$regex) {
302290
// Handle later
303291
} else {
304-
patterns.push(`${name} = '${fieldValue}'`);
292+
patterns.push(`$${index}:raw = $${index + 1}::text`);
293+
values.push(name, fieldValue);
294+
index += 2;
305295
}
306296
}
307297
} else if (fieldValue === null || fieldValue === undefined) {

0 commit comments

Comments
 (0)