aboutsummaryrefslogtreecommitdiffstats
path: root/epan/protobuf_lang_tree.c
diff options
context:
space:
mode:
authorHuang Qiangxiong <qiangxiong.huang@qq.com>2020-12-27 13:57:17 +0800
committerAndersBroman <a.broman58@gmail.com>2020-12-27 11:32:10 +0000
commitcd2d35c1d2b10fe2916469544cc2951a8979a4dc (patch)
tree12472adbf303c2e4b2d052c7740924d3a5655cb2 /epan/protobuf_lang_tree.c
parent5778b2403ea4fec9762f961a6ba4dbf33fd2ee05 (diff)
Protobuf: fix bugs that parsing complex syntax .proto files
Some .proto files contain complex syntax that does not be described in protobuf official site (https://developers.google.com/protocol-buffers/docs/reference/proto3-spec). 1. Update 'epan/protobuf_lang_parser.lemon' to: 1) Support complex option names format (EBNF): optionName = ( ident | "(" fullIdent ")" ) { "." ( ident | "(" fullIdent ")" ) } for example, "option (complex_opt2).(grault) = 654;". 2) Make enum body support 'reserved' section (EBNF): enumBody = "{" { reserved | option | enumField | emptyStatement } "}" 3) Allow the value of field or enumValue option to be "{ ... }" other than constant: enumValueOption = optionName "=" ( constant | customOptionValue ) ";" fieldOption = optionName "=" ( constant | customOptionValue ) ";" 4) Allow 'group' section missing 'label' (for example, in 'oneof' section). 5) Make 'oneof' section support 'option' and 'group' sections (BNF): oneof = "oneof" oneofName "{" { oneofField | option | group | emptyStatement } "}" 6) Ignore unused 'extend' section. 7) Fix the bug of one string being splitted into multi-lines. 2. Update 'epan/protobuf_lang_tree.c' to: 8) Fix the bug of parsing repeated option. 3. Update 'test/suite_dissection.py' to add test case for parsing complex syntax .proto files: test/protobuf_lang_files/complex_proto_files/unittest_custom_options.proto test/protobuf_lang_files/complex_proto_files/complex_syntax.proto and dependency files: test/protobuf_lang_files/well_know_types/google/protobuf/any.proto test/protobuf_lang_files/well_know_types/google/protobuf/descriptor.proto Refer to issue #17046
Diffstat (limited to 'epan/protobuf_lang_tree.c')
-rw-r--r--epan/protobuf_lang_tree.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/epan/protobuf_lang_tree.c b/epan/protobuf_lang_tree.c
index 25c9d2e1ac..b269ad3439 100644
--- a/epan/protobuf_lang_tree.c
+++ b/epan/protobuf_lang_tree.c
@@ -1009,7 +1009,17 @@ pbl_add_child(pbl_node_t* parent, pbl_node_t* child)
}
node = (pbl_node_t*) g_hash_table_lookup(parent->children_by_name, child->name);
- if (node && child->file && parent->file
+ if (node && node->nodetype == PBL_OPTION && child->nodetype == PBL_OPTION
+ && ((pbl_option_descriptor_t*)node)->value && ((pbl_option_descriptor_t*)child)->value) {
+ /* repeated option can be set many times like:
+ string fieldWithComplexOption5 = 5 [(rules).repeated_int = 1, (rules).repeated_int = 2];
+ we just merge the old value and new value in format /old_value "," new_value/.
+ */
+ gchar* oval = ((pbl_option_descriptor_t*)node)->value;
+ gchar* nval = ((pbl_option_descriptor_t*)child)->value;
+ ((pbl_option_descriptor_t*)child)->value = g_strconcat(oval, ",", nval, NULL);
+ g_free(nval);
+ } else if (node && child->file && parent->file
&& child->file->pool && child->file->pool->error_cb) {
child->file->pool->error_cb(
"Protobuf: Warning: \"%s\" of [%s:%d] is already defined in file [%s:%d].\n",