Detect and fail on missing closing brackets #1366

This commit is contained in:
Mike Farah 2022-10-08 12:44:47 +11:00
parent 48c36efe07
commit 1b8d399de4
3 changed files with 25 additions and 12 deletions

View File

@ -70,7 +70,7 @@ func (p *expressionParserImpl) createExpressionTree(postFixPath []*Operation) (*
stack = append(stack, &newNode) stack = append(stack, &newNode)
} }
if len(stack) != 1 { if len(stack) != 1 {
return nil, fmt.Errorf("Bad expression, please check expression syntax") return nil, fmt.Errorf("bad expression, please check expression syntax")
} }
return stack[0], nil return stack[0], nil
} }

View File

@ -11,33 +11,38 @@ func getExpressionParser() ExpressionParserInterface {
return ExpressionParser return ExpressionParser
} }
func TestParserNoMatchingCloseBracket(t *testing.T) {
_, err := getExpressionParser().ParseExpression(".cat | with(.;.bob")
test.AssertResultComplex(t, "bad expression - probably missing close bracket on WITH", err.Error())
}
func TestParserNoMatchingCloseCollect(t *testing.T) { func TestParserNoMatchingCloseCollect(t *testing.T) {
_, err := getExpressionParser().ParseExpression("[1,2") _, err := getExpressionParser().ParseExpression("[1,2")
test.AssertResultComplex(t, "Bad expression, could not find matching `]`", err.Error()) test.AssertResultComplex(t, "bad expression, could not find matching `]`", err.Error())
} }
func TestParserNoMatchingCloseObjectInCollect(t *testing.T) { func TestParserNoMatchingCloseObjectInCollect(t *testing.T) {
_, err := getExpressionParser().ParseExpression(`[{"b": "c"]`) _, err := getExpressionParser().ParseExpression(`[{"b": "c"]`)
test.AssertResultComplex(t, "Bad expression, could not find matching `}`", err.Error()) test.AssertResultComplex(t, "bad expression, could not find matching `}`", err.Error())
} }
func TestParserNoMatchingCloseInCollect(t *testing.T) { func TestParserNoMatchingCloseInCollect(t *testing.T) {
_, err := getExpressionParser().ParseExpression(`[(.a]`) _, err := getExpressionParser().ParseExpression(`[(.a]`)
test.AssertResultComplex(t, "Bad expression, could not find matching `)`", err.Error()) test.AssertResultComplex(t, "bad expression, could not find matching `)`", err.Error())
} }
func TestParserNoMatchingCloseCollectObject(t *testing.T) { func TestParserNoMatchingCloseCollectObject(t *testing.T) {
_, err := getExpressionParser().ParseExpression(`{"a": "b"`) _, err := getExpressionParser().ParseExpression(`{"a": "b"`)
test.AssertResultComplex(t, "Bad expression, could not find matching `}`", err.Error()) test.AssertResultComplex(t, "bad expression, could not find matching `}`", err.Error())
} }
func TestParserNoMatchingCloseCollectInCollectObject(t *testing.T) { func TestParserNoMatchingCloseCollectInCollectObject(t *testing.T) {
_, err := getExpressionParser().ParseExpression(`{"b": [1}`) _, err := getExpressionParser().ParseExpression(`{"b": [1}`)
test.AssertResultComplex(t, "Bad expression, could not find matching `]`", err.Error()) test.AssertResultComplex(t, "bad expression, could not find matching `]`", err.Error())
} }
func TestParserNoMatchingCloseBracketInCollectObject(t *testing.T) { func TestParserNoMatchingCloseBracketInCollectObject(t *testing.T) {
_, err := getExpressionParser().ParseExpression(`{"b": (1}`) _, err := getExpressionParser().ParseExpression(`{"b": (1}`)
test.AssertResultComplex(t, "Bad expression, could not find matching `)`", err.Error()) test.AssertResultComplex(t, "bad expression, could not find matching `)`", err.Error())
} }
func TestParserNoArgsForTwoArgOp(t *testing.T) { func TestParserNoArgsForTwoArgOp(t *testing.T) {
@ -72,5 +77,5 @@ func TestParserOneArgForOneArgOp(t *testing.T) {
func TestParserExtraArgs(t *testing.T) { func TestParserExtraArgs(t *testing.T) {
_, err := getExpressionParser().ParseExpression("sortKeys(.) explode(.)") _, err := getExpressionParser().ParseExpression("sortKeys(.) explode(.)")
test.AssertResultComplex(t, "Bad expression, please check expression syntax", err.Error()) test.AssertResultComplex(t, "bad expression, please check expression syntax", err.Error())
} }

View File

@ -27,11 +27,11 @@ func popOpToResult(opStack []*token, result []*Operation) ([]*token, []*Operatio
func validateNoOpenTokens(token *token) error { func validateNoOpenTokens(token *token) error {
if token.TokenType == openCollect { if token.TokenType == openCollect {
return fmt.Errorf(("Bad expression, could not find matching `]`")) return fmt.Errorf(("bad expression, could not find matching `]`"))
} else if token.TokenType == openCollectObject { } else if token.TokenType == openCollectObject {
return fmt.Errorf(("Bad expression, could not find matching `}`")) return fmt.Errorf(("bad expression, could not find matching `}`"))
} else if token.TokenType == openBracket { } else if token.TokenType == openBracket {
return fmt.Errorf(("Bad expression, could not find matching `)`")) return fmt.Errorf(("bad expression, could not find matching `)`"))
} }
return nil return nil
} }
@ -104,7 +104,7 @@ func (p *expressionPostFixerImpl) ConvertToPostfix(infixTokens []*token) ([]*Ope
opStack, result = popOpToResult(opStack, result) opStack, result = popOpToResult(opStack, result)
} }
if len(opStack) == 0 { if len(opStack) == 0 {
return nil, errors.New("Bad path expression, got close brackets without matching opening bracket") return nil, errors.New("bad expression, got close brackets without matching opening bracket")
} }
// now we should have ( as the last element on the opStack, get rid of it // now we should have ( as the last element on the opStack, get rid of it
opStack = opStack[0 : len(opStack)-1] opStack = opStack[0 : len(opStack)-1]
@ -124,6 +124,14 @@ func (p *expressionPostFixerImpl) ConvertToPostfix(infixTokens []*token) ([]*Ope
} }
log.Debugf("opstackLen: %v", len(opStack)) log.Debugf("opstackLen: %v", len(opStack))
if len(opStack) > 0 {
log.Debugf("opstack:")
for _, token := range opStack {
log.Debugf("- %v", token.toString(true))
}
return nil, fmt.Errorf("bad expression - probably missing close bracket on %v", opStack[len(opStack)-1].toString(false))
}
if log.IsEnabledFor(logging.DEBUG) { if log.IsEnabledFor(logging.DEBUG) {
log.Debugf("PostFix Result:") log.Debugf("PostFix Result:")