Commit 7eb4c609 authored by Vladimir Glavnyy's avatar Vladimir Glavnyy Committed by Wouter van Oortmerssen

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.
parent af3c5981
...@@ -10,7 +10,7 @@ include = `include` string\_constant `;` ...@@ -10,7 +10,7 @@ include = `include` string\_constant `;`
namespace\_decl = `namespace` ident ( `.` ident )* `;` namespace\_decl = `namespace` ident ( `.` ident )* `;`
attribute\_decl = `attribute` string\_constant `;` attribute\_decl = `attribute` ident | `"`ident`"` `;`
type\_decl = ( `table` | `struct` ) ident metadata `{` field\_decl+ `}` type\_decl = ( `table` | `struct` ) ident metadata `{` field\_decl+ `}`
......
...@@ -425,8 +425,7 @@ CheckedError Parser::Next() { ...@@ -425,8 +425,7 @@ CheckedError Parser::Next() {
if (IsIdentifierStart(c)) { if (IsIdentifierStart(c)) {
// Collect all chars of an identifier: // Collect all chars of an identifier:
const char *start = cursor_ - 1; const char *start = cursor_ - 1;
while (isalnum(static_cast<unsigned char>(*cursor_)) || while (isalnum(static_cast<unsigned char>(*cursor_)) || *cursor_ == '_')
*cursor_ == '_')
cursor_++; cursor_++;
attribute_.append(start, cursor_); attribute_.append(start, cursor_);
token_ = kTokenIdentifier; token_ = kTokenIdentifier;
...@@ -1223,10 +1222,13 @@ CheckedError Parser::ParseMetaData(SymbolTable<Value> *attributes) { ...@@ -1223,10 +1222,13 @@ CheckedError Parser::ParseMetaData(SymbolTable<Value> *attributes) {
NEXT(); NEXT();
for (;;) { for (;;) {
auto name = attribute_; 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()) if (known_attributes_.find(name) == known_attributes_.end())
return Error("user define attributes must be declared before use: " + return Error("user define attributes must be declared before use: " +
name); name);
NEXT();
auto e = new Value(); auto e = new Value();
attributes->Add(name, e); attributes->Add(name, e);
if (Is(':')) { if (Is(':')) {
...@@ -2453,7 +2455,11 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths, ...@@ -2453,7 +2455,11 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
} else if (IsIdent("attribute")) { } else if (IsIdent("attribute")) {
NEXT(); NEXT();
auto name = attribute_; auto name = attribute_;
EXPECT(kTokenStringConstant); if (Is(kTokenIdentifier)) {
NEXT();
} else {
EXPECT(kTokenStringConstant);
}
EXPECT(';'); EXPECT(';');
known_attributes_[name] = false; known_attributes_[name] = false;
} else if (IsIdent("rpc_service")) { } else if (IsIdent("rpc_service")) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment