From: Vladimir Glavnyy <31897320+vglavnyy@users.noreply.github.com> Date: Fri, 6 Apr 2018 16:07:59 +0000 (+0700) Subject: An user-defined attribute name validation (#4689) X-Git-Tag: v1.10.0~139 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7eb4c6098e88f7bee04a2d6baf2da28ff721219f;p=platform%2Fupstream%2Fflatbuffers.git An user-defined attribute name validation (#4689) * User-declared attribute should be either identifier or string with the identifier. * Attribute can be identifier or string in metadata. --- diff --git a/docs/source/Grammar.md b/docs/source/Grammar.md index 84e762c..bf79596 100644 --- a/docs/source/Grammar.md +++ b/docs/source/Grammar.md @@ -10,7 +10,7 @@ include = `include` string\_constant `;` namespace\_decl = `namespace` ident ( `.` ident )* `;` -attribute\_decl = `attribute` string\_constant `;` +attribute\_decl = `attribute` ident | `"`ident`"` `;` type\_decl = ( `table` | `struct` ) ident metadata `{` field\_decl+ `}` diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index b16e3e1..3a1d7b9 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -425,8 +425,7 @@ CheckedError Parser::Next() { if (IsIdentifierStart(c)) { // Collect all chars of an identifier: const char *start = cursor_ - 1; - while (isalnum(static_cast(*cursor_)) || - *cursor_ == '_') + while (isalnum(static_cast(*cursor_)) || *cursor_ == '_') cursor_++; attribute_.append(start, cursor_); token_ = kTokenIdentifier; @@ -1223,10 +1222,13 @@ CheckedError Parser::ParseMetaData(SymbolTable *attributes) { NEXT(); for (;;) { auto name = attribute_; - EXPECT(kTokenIdentifier); + if (false == (Is(kTokenIdentifier) || Is(kTokenStringConstant))) + return Error("attribute name must be either identifier or string: " + + name); if (known_attributes_.find(name) == known_attributes_.end()) return Error("user define attributes must be declared before use: " + name); + NEXT(); auto e = new Value(); attributes->Add(name, e); if (Is(':')) { @@ -2453,7 +2455,11 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths, } else if (IsIdent("attribute")) { NEXT(); auto name = attribute_; - EXPECT(kTokenStringConstant); + if (Is(kTokenIdentifier)) { + NEXT(); + } else { + EXPECT(kTokenStringConstant); + } EXPECT(';'); known_attributes_[name] = false; } else if (IsIdent("rpc_service")) {