aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorHuang Qiangxiong <qiangxiong.huang@qq.com>2020-11-04 12:38:23 +0000
committerWireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2020-11-05 07:08:09 +0000
commit1fff3cb10654441baac206360e19e33e81ede799 (patch)
tree0bec7a45d0d022e1bd81244ec2c1d9f463bfa9da /epan
parent30c392f166475a251ea8c3cfde305b40971bbbef (diff)
Protobuf: fix bug about parsing negative enum value number
Change PT_DECIMALLIT, PT_OCTALLIT and PT_HEXLIT tokens to uint64 type, and make PT_IDENT excluding '-' numbers which will be parsed in protobuf_lang.y. That negative enum number and number type of constant can be correctly parsed. Note, intLit is uint32 for parsing fieldNumber and enumNumber, but might be uint64 as constant. close #16988
Diffstat (limited to 'epan')
-rw-r--r--epan/protobuf_lang.y.in29
-rw-r--r--epan/protobuf_lang_scanner.l10
2 files changed, 28 insertions, 11 deletions
diff --git a/epan/protobuf_lang.y.in b/epan/protobuf_lang.y.in
index 9d81a64326..ad567e00dc 100644
--- a/epan/protobuf_lang.y.in
+++ b/epan/protobuf_lang.y.in
@@ -92,6 +92,7 @@ DIAG_OFF_BYACC
char* sval;
pbl_node_t* node;
int ival;
+ guint64 u64val;
};
/* operations or symbols tokens */
@@ -104,7 +105,7 @@ DIAG_OFF_BYACC
%right <sval> PT_REPEATED PT_ONEOF PT_MAP PT_RESERVED PT_ENUM PT_GROUP PT_EXTEND PT_EXTENSIONS
%right <sval> PT_MESSAGE PT_SERVICE PT_RPC PT_STREAM PT_RETURNS PT_TO PT_PROTO2 PT_PROTO3 PT_IDENT PT_STRLIT
-%token <ival> PT_DECIMALLIT PT_OCTALLIT PT_HEXLIT
+%token <u64val> PT_DECIMALLIT PT_OCTALLIT PT_HEXLIT
%type <sval> optionName label type keyType messageName enumName
%type <sval> streamName fieldName oneofName mapName serviceName rpcName messageType
@@ -114,7 +115,8 @@ DIAG_OFF_BYACC
%type <node> enum enumBody enumField service serviceBody stream streamDecl
%type <node> fieldOptions fieldOption oneof oneofBody mapField group extend extendBody
-%type <ival> intLit fieldNumber
+%type <u64val> intLit
+%type <ival> fieldNumber enumNumber
/* We don't care about following nodes:
syntax import package option enumValueOptions enumValueOption rpcBody streamBody
@@ -262,14 +264,20 @@ enumBody:
| enumBody emptyStatement
;
-/* v2/v3: enumField = ident "=" intLit [ "[" enumValueOption { "," enumValueOption } "]" ]";" */
+/* v2/v3: enumField = ident "=" [ "-" ] intLit [ "[" enumValueOption { "," enumValueOption } "]" ]";" */
enumField:
- exIdent PT_ASSIGN intLit PT_LBRACKET enumValueOptions PT_RBRACKET PT_SEMICOLON
+ exIdent PT_ASSIGN enumNumber PT_LBRACKET enumValueOptions PT_RBRACKET PT_SEMICOLON
{ $$ = pbl_create_enum_value_node(state->file, $1, $3); }
-| exIdent PT_ASSIGN intLit
+| exIdent PT_ASSIGN enumNumber
{ $$ = pbl_create_enum_value_node(state->file, $1, $3); }
;
+/* v2/v3: must be in the range of a 32-bit integer. negative values are not recommended. */
+enumNumber: intLit { $$ = (int)$1; }
+| PT_PLUS intLit { $$ = (int)$2; }
+| PT_MINUS intLit { $$ = -(int)$2; }
+;
+
/* v2/v3: enumValueOption { "," enumValueOption } */
enumValueOptions:
enumValueOption
@@ -365,7 +373,10 @@ label: PT_REQUIRED | PT_OPTIONAL | PT_REPEATED;
*/
type: exIdent;
-fieldNumber: intLit;
+/* v2/v3: The smallest field number is 1, and the largest is 2^29 - 1, or 536,870,911. */
+fieldNumber: intLit { $$ = (int)$1; }
+| PT_PLUS intLit { $$ = (int)$2; }
+;
/* v2/v3: fieldOptions = fieldOption { "," fieldOption } */
fieldOptions:
@@ -503,6 +514,12 @@ emptyStatement: PT_SEMICOLON;
/* constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) | strLit | boolLit */
constant: exIdent | strLit
+| intLit { $$ = pbl_store_string_token(state, g_strdup_printf("%" G_GUINT64_FORMAT, $1)); }
+| PT_PLUS intLit { $$ = pbl_store_string_token(state, g_strdup_printf("%" G_GUINT64_FORMAT, $2)); }
+| PT_MINUS intLit { $$ = pbl_store_string_token(state, g_strdup_printf("-%" G_GUINT64_FORMAT, $2)); }
+/* This cover floatLit. In addition, boolLit is parsed as exIdent */
+| PT_PLUS exIdent { $$ = pbl_store_string_token(state, g_strconcat("+", $2, NULL)); }
+| PT_MINUS exIdent { $$ = pbl_store_string_token(state, g_strconcat("-", $2, NULL)); }
;
exIdent: PT_IDENT
diff --git a/epan/protobuf_lang_scanner.l b/epan/protobuf_lang_scanner.l
index f1edcbabf9..1898666112 100644
--- a/epan/protobuf_lang_scanner.l
+++ b/epan/protobuf_lang_scanner.l
@@ -166,12 +166,12 @@ to yylval->sval = strdup_and_store(yyscanner, yytext); retur
["']proto3["'] yylval->sval = strdup_and_store(yyscanner, yytext); return PT_PROTO3;
/* intLit values */
-0|[1-9][0-9]* yylval->ival = atoi(yytext); return PT_DECIMALLIT;
-0[0-7]* sscanf(yytext+1, "%o", &yylval->ival); return PT_OCTALLIT;
-0[xX][0-9a-fA-F]+ sscanf(yytext+2, "%x", &yylval->ival); return PT_HEXLIT;
+0|[1-9][0-9]* yylval->u64val = g_ascii_strtoull(yytext, NULL, 10); return PT_DECIMALLIT;
+0[0-7]* yylval->u64val = g_ascii_strtoull(yytext+1, NULL, 8); return PT_OCTALLIT;
+0[xX][0-9a-fA-F]+ yylval->u64val = g_ascii_strtoull(yytext+2, NULL, 16); return PT_HEXLIT;
/* Using extended identifier because we care only about position */
-[a-zA-Z0-9_.+-]+ yylval->sval = strdup_and_store(yyscanner, yytext); return PT_IDENT;
+[a-zA-Z0-9_][a-zA-Z0-9_.+-]* yylval->sval = strdup_and_store(yyscanner, yytext); return PT_IDENT;
\"(\\.|\"\"|[^"\n"])*\" yylval->sval = g_strndup(yytext + 1, strlen(yytext) - 2); return PT_STRLIT;
\'(\\.|\'\'|[^"\n"])*\' yylval->sval = g_strndup(yytext + 1, strlen(yytext) - 2); return PT_STRLIT;
@@ -196,4 +196,4 @@ strdup_and_store(void* yyscanner, const char* text) {
/*
* Turn diagnostics back on, so we check the code that we've written.
*/
-DIAG_ON_FLEX \ No newline at end of file
+DIAG_ON_FLEX