Skip to content

Commit ec76bc9

Browse files
committed
BUG#27361584: prevent invalid usage of globstars
Globstars ("**") can be used to create an implicit link between two elements of a document path. They make it easier and less verbose to perform operations on a deeper level of a document. However, they are only valid in a specific setting where the both the leading and trailing elements in the document path are correctly specified, like the following: '$.foo**.bar' '$**.bar' In practice, this means they cannot be used as the last item in a document path. The expression parser does not account for invalid usage of a globstar, for instance, like in the following instances. '$.foo.**bar' '$.foo**' '$**' This patch addresses this issue and updates the sub-parser for "documentPath" expressions to explicitely fail for the cases where a globstar is the last item in such an expression. Change-Id: If16c9e1d81af09e912026a566ecb4be173585c89
1 parent 174552b commit ec76bc9

File tree

3 files changed

+16
-13
lines changed

3 files changed

+16
-13
lines changed

lib/ExprParser/lib/grammar/collectionOrTableExpressions/documentPath.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ const PARSER_OPTIONS = {
4848
* .foo.*
4949
* .foo[*]
5050
*/
51-
const parser = _ => r => r.documentPathItem.many();
51+
const parser = _ => r => r.documentPathItem
52+
.many()
53+
.assert(items => {
54+
// The last item in the document path cannot be a globstar ("**").
55+
if (items.length && items[items.length - 1].type === 'doubleAsterisk') {
56+
return false;
57+
}
58+
59+
return true;
60+
});
5261

5362
module.exports = { name: PARSER_OPTIONS.NAME, parser };

test/unit/ExprParser/columnIdent.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,8 +435,7 @@ describe('ExprParser', () => {
435435
expect(() => Parser.parse("foo->'$foo.[1]'", { type, mode })).to.throw();
436436
expect(() => Parser.parse("foo->'$foo*[1]'", { type, mode })).to.throw();
437437
expect(() => Parser.parse("foo->'$foo.*[1]'", { type, mode })).to.throw();
438-
// TODO(Rui): BUG#27361584
439-
// expect(() => Parser.parse("foo->'$**'", { type, mode })).to.throw();
438+
expect(() => Parser.parse("foo->'$**'", { type, mode })).to.throw();
440439
expect(() => Parser.parse("foo->'$foo**bar'", { type, mode })).to.throw();
441440
expect(() => Parser.parse("foo->'$foo.**bar'", { type, mode })).to.throw();
442441
expect(() => Parser.parse("doc->'foo**.bar'", { type, mode })).to.throw();

test/unit/ExprParser/documentField.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,7 @@ describe('ExprParser', () => {
189189
});
190190
});
191191

192-
// TODO(Rui): BUG#27361584
193-
it.skip('fails to parse a path to multiple fields linked by a globstar', () => {
192+
it('fails to parse a path to multiple fields linked by a globstar', () => {
194193
expect(() => Parser.parse('$**', { type })).to.throw();
195194
return expect(() => Parser.parse('$.foo**', { type })).to.throw();
196195
});
@@ -328,8 +327,7 @@ describe('ExprParser', () => {
328327
});
329328
});
330329

331-
// TODO(Rui): BUG#27361584
332-
it.skip('fails to parse a path to multiple fields linked by a globstar', () => {
330+
it('fails to parse a path to multiple fields linked by a globstar', () => {
333331
expect(() => Parser.parse('**', { type })).to.throw();
334332
return expect(() => Parser.parse('foo**', { type })).to.throw();
335333
});
@@ -341,17 +339,14 @@ describe('ExprParser', () => {
341339
expect(() => Parser.parse('.doc', { type })).to.throw();
342340
expect(() => Parser.parse('**', { type })).to.throw();
343341
expect(() => Parser.parse('**foo', { type })).to.throw();
344-
// TODO(Rui): BUG#27361584
345-
// expect(() => Parser.parse('_**', { type })).to.throw();
342+
expect(() => Parser.parse('_**', { type })).to.throw();
346343
expect(() => Parser.parse('_**[*]_**._', { type })).to.throw();
347344
expect(() => Parser.parse('_**[*]._.**._', { type })).to.throw();
348345
expect(() => Parser.parse('_**[*]_.**._', { type })).to.throw();
349-
// TODO(Rui): BUG#27361584
350-
// expect(() => Parser.parse('$.foo**', { type })).to.throw();
346+
expect(() => Parser.parse('$.foo**', { type })).to.throw();
351347
expect(() => Parser.parse('$.foo.**.bar', { type })).to.throw();
352348
expect(() => Parser.parse('$.foo[**]', { type })).to.throw();
353-
// TODO(Rui): BUG#27361584
354-
// expect(() => Parser.parse('$**', { type })).to.throw();
349+
expect(() => Parser.parse('$**', { type })).to.throw();
355350
expect(() => Parser.parse('$.**', { type })).to.throw();
356351
expect(() => Parser.parse('$.**bar', { type })).to.throw();
357352
expect(() => Parser.parse('$.**".bar"', { type })).to.throw();

0 commit comments

Comments
 (0)