diff options
author | Huang Qiangxiong <qiangxiong.huang@qq.com> | 2020-12-27 13:57:17 +0800 |
---|---|---|
committer | AndersBroman <a.broman58@gmail.com> | 2020-12-27 11:32:10 +0000 |
commit | cd2d35c1d2b10fe2916469544cc2951a8979a4dc (patch) | |
tree | 12472adbf303c2e4b2d052c7740924d3a5655cb2 /epan/protobuf_lang_tree.c | |
parent | 5778b2403ea4fec9762f961a6ba4dbf33fd2ee05 (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.c | 12 |
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", |