From 72d16876583aa82a05865e4e213a475e962ad134 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Fri, 1 Oct 2021 18:23:30 -0500 Subject: [PATCH] parser: disallow duplicate members Check each constant as it is recognized to ensure its name does not duplicate an already-defined constant. Check each message member as it is recognized to ensure its name does not duplicate an already-defined member. Also check its id value to ensure the same value isn't used more than once. Check each struct member as it is recognized to ensure its name does not duplicate an already-defined member. Signed-off-by: Alex Elder Message-Id: <20211001232338.769309-27-elder@linaro.org> Signed-off-by: Bjorn Andersson --- parser.c | 19 +++++++++++++++++++ tests/duplicate_const.qmi | 21 +++++++++++++++++++++ tests/duplicate_message_name.qmi | 21 +++++++++++++++++++++ tests/duplicate_message_val.qmi | 22 ++++++++++++++++++++++ tests/duplicate_struct_name.qmi | 30 ++++++++++++++++++++++++++++++ 5 files changed, 113 insertions(+) create mode 100644 tests/duplicate_const.qmi create mode 100644 tests/duplicate_message_name.qmi create mode 100644 tests/duplicate_message_val.qmi create mode 100644 tests/duplicate_struct_name.qmi diff --git a/parser.c b/parser.c index bc3454e..b9c2efd 100644 --- a/parser.c +++ b/parser.c @@ -329,6 +329,7 @@ static void qmi_package_parse(void) static void qmi_const_parse() { + struct qmi_const *qcm; struct qmi_const *qc; struct token num_tok; struct token id_tok; @@ -338,6 +339,10 @@ static void qmi_const_parse() token_expect(TOK_NUM, &num_tok); token_expect(';', NULL); + list_for_each_entry(qcm, &qmi_consts, node) + if (!strcmp(qcm->name, id_tok.str)) + yyerror("duplicate constant \"%s\"", qcm->name); + qc = memalloc(sizeof(struct qmi_const)); qc->name = id_tok.str; qc->value = num_tok.num; @@ -395,6 +400,15 @@ static void qmi_message_parse(enum message_type message_type) token_expect(TOK_NUM, &num_tok); token_expect(';', NULL); + list_for_each_entry(qmm, &qm->members, node) { + if (!strcmp(qmm->name, id_tok.str)) + yyerror("duplicate message member \"%s\"", + qmm->name); + if (qmm->id == type_tok.num) + yyerror("duplicate message member number %u", + qmm->id); + } + qmm = memalloc(sizeof(struct qmi_message_member)); qmm->name = id_tok.str; qmm->type = type_tok.num; @@ -439,6 +453,11 @@ static void qmi_struct_parse(void) token_expect(TOK_ID, &id_tok); token_expect(';', NULL); + list_for_each_entry(qsm, &qs->members, node) + if (!strcmp(qsm->name, id_tok.str)) + yyerror("duplicate struct member \"%s\"", + qsm->name); + qsm = memalloc(sizeof(struct qmi_struct_member)); qsm->name = id_tok.str; qsm->type = type_tok.num; diff --git a/tests/duplicate_const.qmi b/tests/duplicate_const.qmi new file mode 100644 index 0000000..9c087e0 --- /dev/null +++ b/tests/duplicate_const.qmi @@ -0,0 +1,21 @@ +package test; + +const TEST_REQUEST_RESPONSE = 35; +const TEST_REQUEST_RESPONSE = 35; + +struct qmi_result { + u16 result; + u16 error; +}; + +request test_request { + required u8 test_number = 0x12; +} = 0x23; + +response test_response { + required qmi_result r = 2; +} = 043; + +indication test_indication { + optional u64 value = 0x99; +} = 0x7; diff --git a/tests/duplicate_message_name.qmi b/tests/duplicate_message_name.qmi new file mode 100644 index 0000000..7b9627c --- /dev/null +++ b/tests/duplicate_message_name.qmi @@ -0,0 +1,21 @@ +package test; + +const TEST_REQUEST_RESPONSE = 35; + +struct qmi_result { + u16 result; + u16 error; +}; + +request test_request { + required u8 test_number = 0x12; + required u16 test_number = 0x11; +} = 0x23; + +response test_response { + required qmi_result r = 2; +} = 043; + +indication test_indication { + optional u64 value = 0x99; +} = 0x7; diff --git a/tests/duplicate_message_val.qmi b/tests/duplicate_message_val.qmi new file mode 100644 index 0000000..7f84e53 --- /dev/null +++ b/tests/duplicate_message_val.qmi @@ -0,0 +1,22 @@ +package test; + +const TEST_REQUEST_RESPONSE = 35; +const TEST_INDICATION = 07; + +struct qmi_result { + u16 result; + u16 error; +}; + +request test_request { + required u8 test_number = 0x1; + optional u16 test_number2 = 0x1; +} = 0x23; + +response test_response { + required qmi_result r = 2; +} = 043; + +indication test_indication { + optional u64 value = 0x99; +} = 0x7; diff --git a/tests/duplicate_struct_name.qmi b/tests/duplicate_struct_name.qmi new file mode 100644 index 0000000..96f741a --- /dev/null +++ b/tests/duplicate_struct_name.qmi @@ -0,0 +1,30 @@ +package test; + +const TEST_REQUEST_RESPONSE = 35; +const TEST_INDICATION = 07; + +struct qmi_result { + u16 result; + u16 error; +}; + +struct test_struct { + u8 test_u8; + u8 test_u8; + u16 test_u16; + u32 test_u32; + u64 test_u64; +}; + +request test_request { + optional test_struct foo = 0x1; + required u8 test_number = 0x12; +} = 0x23; + +response test_response { + required qmi_result r = 2; +} = 043; + +indication test_indication { + optional u64 value = 0x99; +} = 0x7;