From 2107554d67b73bf8b6be15120bcc6bd3ce694096 Mon Sep 17 00:00:00 2001 From: TATSUNO Yasuhiro Date: Tue, 24 Aug 2021 08:49:10 +0900 Subject: [PATCH] Throws if path token starts with underscore --- db/conditionParser.js | 66 ++++++++++++++++++++++++++++++++++++++-- db/conditionParser.pegjs | 13 ++++++-- test/putItem.js | 12 ++++++++ 3 files changed, 86 insertions(+), 5 deletions(-) diff --git a/db/conditionParser.js b/db/conditionParser.js index 4a05fdf..27ed7d7 100644 --- a/db/conditionParser.js +++ b/db/conditionParser.js @@ -1578,7 +1578,7 @@ function peg$parse(input, options) { if (s5 !== peg$FAILED) { s6 = peg$parse_(); if (s6 !== peg$FAILED) { - s7 = peg$parseIdentifier(); + s7 = peg$parsePathIdentifier(); if (s7 !== peg$FAILED) { peg$savedPos = s3; s4 = peg$c50(s1, s7); @@ -1689,7 +1689,7 @@ function peg$parse(input, options) { if (s5 !== peg$FAILED) { s6 = peg$parse_(); if (s6 !== peg$FAILED) { - s7 = peg$parseIdentifier(); + s7 = peg$parsePathIdentifier(); if (s7 !== peg$FAILED) { peg$savedPos = s3; s4 = peg$c50(s1, s7); @@ -1731,7 +1731,7 @@ function peg$parse(input, options) { function peg$parseGroupedPathExpression() { var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - s0 = peg$parseIdentifier(); + s0 = peg$parsePathIdentifier(); if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 40) { @@ -1914,6 +1914,52 @@ function peg$parse(input, options) { return s0; } + function peg$parsePathIdentifier() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + s1 = peg$currPos; + peg$silentFails++; + s2 = peg$parseReservedWord(); + peg$silentFails--; + if (s2 === peg$FAILED) { + s1 = void 0; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s2 = peg$parsePathIdentifierStart(); + if (s2 !== peg$FAILED) { + s3 = []; + s4 = peg$parseIdentifierPart(); + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = peg$parseIdentifierPart(); + } + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c54(s2, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$parseExpressionAttributeName(); + } + + return s0; + } + function peg$parseIdentifierStart() { var s0; @@ -1937,6 +1983,20 @@ function peg$parse(input, options) { return s0; } + function peg$parsePathIdentifierStart() { + var s0; + + if (peg$c55.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c56); } + } + + return s0; + } + function peg$parseIdentifierPart() { var s0; diff --git a/db/conditionParser.pegjs b/db/conditionParser.pegjs index 7428e3a..1729034 100644 --- a/db/conditionParser.pegjs +++ b/db/conditionParser.pegjs @@ -343,7 +343,7 @@ PathExpression _ '[' _ ix:[0-9]+ _ ']' { return +(ix.join('')) } - / _ '.' _ prop:Identifier { + / _ '.' _ prop:PathIdentifier { return prop } )* { @@ -351,7 +351,7 @@ PathExpression } GroupedPathExpression - = Identifier + = PathIdentifier / '(' _ '(' _ path:PathExpression _ ')' _ ')' { redundantParensError() return path @@ -366,10 +366,19 @@ Identifier } / ExpressionAttributeName +PathIdentifier + = !ReservedWord head:PathIdentifierStart tail:IdentifierPart* { + return head + tail.join('') + } + / ExpressionAttributeName + IdentifierStart = [a-zA-Z] / '_' +PathIdentifierStart + = [a-zA-Z] + IdentifierPart = IdentifierStart / [0-9] diff --git a/test/putItem.js b/test/putItem.js index 63ed204..b2ce24d 100644 --- a/test/putItem.js +++ b/test/putItem.js @@ -551,6 +551,18 @@ describe('putItem', function() { helpers.deleteWhenActive(table.TableName) }) }) + + it('should return ValidationException if path token starts with underscore', function(done) { + async.forEach([ + { ConditionExpression: 'attribute_not_exists(_c)' }, + { ConditionExpression: 'attribute_not_exists(c._d)'}, + ], function(putData, cb) { + putData.TableName = helpers.testRangeTable + putData.Item = {a: {S: 'a'}, b: {S: 'b'}} + assertValidation(putData, /^Invalid ConditionExpression: Syntax error;/, cb) + }, done) + }) + }) // A number can have up to 38 digits precision and can be between 10^-128 to 10^+126