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.
This commit is contained in:
Vladimir Glavnyy
2018-04-06 23:07:59 +07:00
committed by Wouter van Oortmerssen
parent af3c598189
commit 7eb4c6098e
2 changed files with 11 additions and 5 deletions

View File

@@ -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+ `}`

View File

@@ -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<unsigned char>(*cursor_)) ||
*cursor_ == '_')
while (isalnum(static_cast<unsigned char>(*cursor_)) || *cursor_ == '_')
cursor_++;
attribute_.append(start, cursor_);
token_ = kTokenIdentifier;
@@ -1223,10 +1222,13 @@ CheckedError Parser::ParseMetaData(SymbolTable<Value> *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")) {