From 17552f0931ebc68557ec56b1991aafb227557f34 Mon Sep 17 00:00:00 2001 From: Lucas Wang Date: Wed, 16 Jan 2019 09:39:07 -0800 Subject: [PATCH] checking item error from lexer and return immediately when found --- gql/parser.go | 10 +++------- gql/parser_mutation.go | 4 ---- gql/parser_test.go | 27 ++++++++++----------------- lex/lexer.go | 12 ++++++++++++ rdf/parse.go | 8 +++----- schema/parse.go | 7 +++---- 6 files changed, 31 insertions(+), 37 deletions(-) diff --git a/gql/parser.go b/gql/parser.go index 8819094dbec..806c4c7222b 100644 --- a/gql/parser.go +++ b/gql/parser.go @@ -464,6 +464,9 @@ func Parse(r Request) (res Result, rerr error) { lexer := lex.Lexer{Input: query} lexer.Run(lexTopLevel) + if err := lexer.ValidateResult(); err != nil { + return res, err + } var qu *GraphQuery it := lexer.NewIterator() @@ -471,9 +474,6 @@ func Parse(r Request) (res Result, rerr error) { for it.Next() { item := it.Item() switch item.Typ { - case lex.ItemError: - return res, x.Errorf(item.Val) - case itemOpType: if item.Val == "mutation" { return res, x.Errorf("Mutation block no longer allowed.") @@ -672,8 +672,6 @@ L2: for it.Next() { item := it.Item() switch item.Typ { - case lex.ItemError: - return nil, x.Errorf(item.Val) case itemName: if name != "" { return nil, x.Errorf("Multiple word query name not allowed.") @@ -2389,8 +2387,6 @@ func godeep(it *lex.ItemIterator, gq *GraphQuery) error { for it.Next() { item := it.Item() switch item.Typ { - case lex.ItemError: - return x.Errorf(item.Val) case lex.ItemEOF: return nil case itemRightCurl: diff --git a/gql/parser_mutation.go b/gql/parser_mutation.go index a28435e5f52..d454d1a1fb4 100644 --- a/gql/parser_mutation.go +++ b/gql/parser_mutation.go @@ -46,10 +46,6 @@ func ParseMutation(mutation string) (*api.Mutation, error) { if item.Typ == itemRightCurl { // mutations must be enclosed in a single block. if it.Next() && it.Item().Typ != lex.ItemEOF { - if it.Item().Typ == lex.ItemError { - return nil, x.Errorf("Unexpected error after end of block: %s", - it.Item().String()) - } return nil, x.Errorf("Unexpected %s after the end of the block.", it.Item().Val) } return &mu, nil diff --git a/gql/parser_test.go b/gql/parser_test.go index 258f563a14f..cca7c7c5ac9 100644 --- a/gql/parser_test.go +++ b/gql/parser_test.go @@ -1229,7 +1229,6 @@ func TestParseIdListError(t *testing.T) { }` _, err := Parse(Request{Str: query}) require.Error(t, err) - require.Contains(t, err.Error(), "Unexpected character [ while parsing request") } func TestParseIdListError2(t *testing.T) { @@ -1855,8 +1854,6 @@ func TestParseVariablesError1(t *testing.T) { ` _, err := Parse(Request{Str: query}) require.Error(t, err) - require.Contains(t, err.Error(), "Variable $") - require.Contains(t, err.Error(), "should be initialised") } func TestParseFilter_root(t *testing.T) { @@ -2162,8 +2159,6 @@ func TestParseFilter_unbalancedbrac(t *testing.T) { ` _, err := Parse(Request{Str: query}) require.Error(t, err) - require.Contains(t, err.Error(), "Unexpected item while parsing @filter") - require.Contains(t, err.Error(), "'{'") } func TestParseFilter_Geo1(t *testing.T) { @@ -2405,7 +2400,6 @@ func TestParseCountError1(t *testing.T) { ` _, err := Parse(Request{Str: query}) require.Error(t, err) - require.Contains(t, err.Error(), "Multiple predicates not allowed in single count") } func TestParseCountError2(t *testing.T) { @@ -2419,7 +2413,6 @@ func TestParseCountError2(t *testing.T) { ` _, err := Parse(Request{Str: query}) require.Error(t, err) - require.Contains(t, err.Error(), "Predicate name cannot be empty") } func TestParseCheckPwd(t *testing.T) { @@ -2620,7 +2613,6 @@ func TestLangsInvalid4(t *testing.T) { _, err := Parse(Request{Str: query}) require.Error(t, err) - require.Contains(t, err.Error(), "Expected directive or language list") } func TestLangsInvalid5(t *testing.T) { @@ -2634,7 +2626,6 @@ func TestLangsInvalid5(t *testing.T) { _, err := Parse(Request{Str: query}) require.Error(t, err) - require.Contains(t, err.Error(), "Expected directive or language list") } func TestLangsInvalid6(t *testing.T) { @@ -2720,8 +2711,6 @@ func TestLangsFilter_error2(t *testing.T) { ` _, err := Parse(Request{Str: query}) require.Error(t, err) - require.Contains(t, err.Error(), "Expected arg after func [alloftext]") - require.Contains(t, err.Error(), "','") } func TestLangsFunction(t *testing.T) { @@ -2940,7 +2929,6 @@ func TestParseFacetsError1(t *testing.T) { ` _, err := Parse(Request{Str: query}) require.Error(t, err) - require.Contains(t, err.Error(), "Expected ( after func name [facet1]") } func TestParseFacetsVarError(t *testing.T) { @@ -3259,7 +3247,6 @@ func TestParseFacetsFail1(t *testing.T) { ` _, err := Parse(Request{Str: query}) require.Error(t, err) - require.Contains(t, err.Error(), "Expected ( after func name [key1]") } func TestParseRepeatArgsError1(t *testing.T) { @@ -3575,8 +3562,6 @@ func TestParseRegexp6(t *testing.T) { ` _, err := Parse(Request{Str: query}) require.Error(t, err) - require.Contains(t, err.Error(), "Expected arg after func [regexp]") - require.Contains(t, err.Error(), "Unclosed regexp") } func TestMain(m *testing.M) { @@ -3669,7 +3654,6 @@ func TestDotsEOF(t *testing.T) { ..` _, err := Parse(Request{Str: query}) require.Error(t, err) - require.Contains(t, err.Error(), "Expected 3 periods") } func TestMathWithoutVarAlias(t *testing.T) { @@ -4330,7 +4314,7 @@ func TestParseMutationTooManyBlocks(t *testing.T) { for _, tc := range tests { mu, err := ParseMutation(tc.m) if tc.errStr != "" { - require.Contains(t, err.Error(), tc.errStr) + require.Error(t, err, "the mutation parsing should have failed") require.Nil(t, mu) } else { require.NoError(t, err) @@ -4421,3 +4405,12 @@ func TestParseGraphQLVarPaginationRootMultiple(t *testing.T) { require.Equal(t, args["after"], "0x123") require.Equal(t, gq.Query[0].Order[0].Attr, "name") } + +func TestWithFuzzCrasherInput(t *testing.T) { + q := "{e(orderasc:#" + r := Request{ + Str: q, + } + _, err := Parse(r) + require.Error(t, err, "should be able to parse the query and return an error:%s", q) +} diff --git a/lex/lexer.go b/lex/lexer.go index 2526acd5985..bc50bacbe11 100644 --- a/lex/lexer.go +++ b/lex/lexer.go @@ -17,6 +17,7 @@ package lex import ( + "errors" "fmt" "unicode/utf8" @@ -131,6 +132,17 @@ type Lexer struct { Mode StateFn // Default state to go back to after reading a token. } +func (l *Lexer) ValidateResult() error { + it := l.NewIterator() + for it.Next() { + item := it.Item() + if item.Typ == ItemError { + return errors.New(item.Val) + } + } + return nil +} + func (l *Lexer) Run(f StateFn) *Lexer { for state := f; state != nil; { // The following statement is useful for debugging. diff --git a/rdf/parse.go b/rdf/parse.go index 9f91df7b3fc..3ecd17c3b8e 100644 --- a/rdf/parse.go +++ b/rdf/parse.go @@ -58,7 +58,9 @@ func Parse(line string) (api.NQuad, error) { Input: line, } l.Run(lexText) - + if err := l.ValidateResult(); err != nil { + return rnq, err + } it := l.NewIterator() var oval string var seenOval bool @@ -143,10 +145,6 @@ L: if rnq.ObjectValue, err = types.ObjectValue(t, p.Value); err != nil { return rnq, err } - - case lex.ItemError: - return rnq, x.Errorf(item.Val) - case itemComment: isCommentLine = true vend = true diff --git a/schema/parse.go b/schema/parse.go index 194bf8872ec..d17d639d64b 100644 --- a/schema/parse.go +++ b/schema/parse.go @@ -304,6 +304,9 @@ func Parse(s string) ([]*pb.SchemaUpdate, error) { var schemas []*pb.SchemaUpdate l := lex.Lexer{Input: s} l.Run(lexText) + if err := l.ValidateResult(); err != nil { + return nil, err + } it := l.NewIterator() for it.Next() { item := it.Item() @@ -320,10 +323,6 @@ func Parse(s string) ([]*pb.SchemaUpdate, error) { return nil, err } schemas = append(schemas, schema) - - case lex.ItemError: - return nil, x.Errorf(item.Val) - case itemNewLine: // pass empty line