From c54d9467d1bf772ecfdfff680b4b224d74fa032d Mon Sep 17 00:00:00 2001 From: v0-e Date: Sat, 20 Jan 2024 20:55:13 +0000 Subject: [PATCH 1/5] Support for default class syntax --- libasn1fix/asn1fix_cws.c | 95 +++++++++++++++++++++++++++++++------ libasn1parser/asn1p_class.c | 46 ++++++++++++++++++ libasn1parser/asn1p_class.h | 4 ++ 3 files changed, 131 insertions(+), 14 deletions(-) diff --git a/libasn1fix/asn1fix_cws.c b/libasn1fix/asn1fix_cws.c index e906ac8db..a026b5c83 100644 --- a/libasn1fix/asn1fix_cws.c +++ b/libasn1fix/asn1fix_cws.c @@ -31,12 +31,6 @@ asn1f_check_class_object(arg_t *arg) { return 0; } - if(!eclass->with_syntax) { - DEBUG("Can't process classes without %s just yet", - "WITH SYNTAX"); - return 0; - } - row = asn1p_ioc_row_new(eclass); assert(row); @@ -266,12 +260,6 @@ asn1f_parse_class_object(arg_t *arg) { DEBUG("Value %s of CLASS %s found at line %d", expr->Identifier, eclass->Identifier, expr->_lineno); - if(!eclass->with_syntax) { - DEBUG("Can't process classes without %s just yet", - "WITH SYNTAX"); - return 0; - } - struct parse_object_key key = { .arg = arg, .expr = expr, @@ -308,10 +296,68 @@ asn1f_parse_class_object(arg_t *arg) { return 0; } -#define SKIPSPACES for(; buf < bend && isspace(*buf); buf++) +#define SKIPSPACES \ + for(; buf < bend && isspace(*buf); buf++) +#define SKIPSPACES_AND_COMMA \ + for(; buf < bend && (isspace(*buf) || *buf==','); buf++) static int -_asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass, +_asn1f_parse_class_object_data_default_syntx(arg_t *arg, asn1p_expr_t *eclass, + struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax, + const uint8_t *buf, const uint8_t *bend, + int optional_mode, const uint8_t **newpos, int counter) { + int ret; + + /* Default syntax: { FieldSetting , * } + * where, FieldSetting ::= PrimitiveFieldName Setting + * and, FieldSetting is a reference and Setting is not + * Contrary to with the defined WITH SYNTAX, + * FieldSetting's can appear in any order */ + + asn1p_expr_t* cm; + SKIPSPACES; + for (; buf < bend; ++buf) { + TQ_FOR(cm, &(eclass->members), next) { + /* PrimitiveFieldName */ + int id_len = strlen(cm->Identifier); + if(id_len > (bend - buf)) { + continue; + } + if(memcmp(buf, cm->Identifier, id_len) == 0) { + buf += strlen(cm->Identifier); + SKIPSPACES; + + /* Setting */ + const uint8_t *p = 0; + for(p = buf; p < bend && (*p) != ','; p++) {} + + struct asn1p_ioc_cell_s *cell; + cell = asn1p_ioc_row_cell_fetch(row, + cm->Identifier); + if(cell == NULL) { + if(newpos) *newpos = buf; + return -1; + } + DEBUG("Reference %s satisfied by %s (%d)", + cm->Identifier, + buf, p - buf); + ret = _asn1f_assign_cell_value(arg, cell, buf, p, counter); + if(ret) return ret; + buf = p; + SKIPSPACES_AND_COMMA; + if(newpos) *newpos = buf; + + break; + } + } + } + + if(newpos) *newpos = buf; + return 0; +} + +static int +_asn1f_parse_class_object_data_defined_syntx(arg_t *arg, asn1p_expr_t *eclass, struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax, const uint8_t *buf, const uint8_t *bend, int optional_mode, const uint8_t **newpos, int counter) { @@ -391,6 +437,27 @@ _asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass, return 0; } +static int +_asn1f_parse_class_object_data(arg_t *arg, asn1p_expr_t *eclass, + struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax, + const uint8_t *buf, const uint8_t *bend, + int optional_mode, const uint8_t **newpos, int counter) { + + if(!eclass->with_syntax) { + /* Assume default syntax */ + return + _asn1f_parse_class_object_data_default_syntx( + arg, eclass, row, syntax, buf, bend, + optional_mode, newpos, counter); + } else { + /* WITH SYNTAX {} */ + return + _asn1f_parse_class_object_data_defined_syntx( + arg, eclass, row, syntax, buf, bend, + optional_mode, newpos, counter); + } +} + static int _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_cell_s *cell, diff --git a/libasn1parser/asn1p_class.c b/libasn1parser/asn1p_class.c index cbe9480e2..a5999a809 100644 --- a/libasn1parser/asn1p_class.c +++ b/libasn1parser/asn1p_class.c @@ -282,6 +282,52 @@ asn1p_wsyntx_clone(asn1p_wsyntx_t *wx) { return nw; } +asn1p_wsyntx_t* +asn1p_wsyntx_default(const struct asn1p_expr_s *eclass) { + /* + * Default syntax: { &literal field , * } + */ + asn1p_wsyntx_t *syntax; + asn1p_expr_t *member; + asn1p_wsyntx_chunk_t *chunk; + + syntax = asn1p_wsyntx_new(); + if(!syntax) { + return NULL; + } + +#define ADD_DC(ctype, ctoken) \ + do { \ + chunk = asn1p_wsyntx_chunk_new(); \ + if(!chunk) { \ + asn1p_wsyntx_free(syntax); \ + return NULL; \ + } \ + chunk->type = ctype; \ + chunk->content.token = strdup(ctoken); \ + TQ_ADD(&(syntax->chunks), chunk, next); \ + } while(0) + + TQ_FOR(member, (&eclass->members), next) { + + /* &literal */ + ADD_DC(WC_LITERAL, member->Identifier); + + /* whitespace */ + ADD_DC(WC_WHITESPACE, " "); + + /* field */ + ADD_DC(WC_FIELD, member->Identifier); + + /* comma separator */ + if(TQ_NEXT(member, next)) { + ADD_DC(WC_LITERAL, ","); + } + } + + return syntax; +} + asn1p_wsyntx_chunk_t * asn1p_wsyntx_chunk_fromstring(char *token, int do_copy) { asn1p_wsyntx_chunk_t *wc; diff --git a/libasn1parser/asn1p_class.h b/libasn1parser/asn1p_class.h index 4c6efab8e..68f751c19 100644 --- a/libasn1parser/asn1p_class.h +++ b/libasn1parser/asn1p_class.h @@ -84,6 +84,10 @@ asn1p_wsyntx_chunk_t *asn1p_wsyntx_chunk_clone(asn1p_wsyntx_chunk_t *); asn1p_wsyntx_t *asn1p_wsyntx_new(void); void asn1p_wsyntx_free(asn1p_wsyntx_t *); asn1p_wsyntx_t *asn1p_wsyntx_clone(asn1p_wsyntx_t *); +/* + * Creates a default syntax of some class + */ +asn1p_wsyntx_t *asn1p_wsyntx_default(const struct asn1p_expr_s *eclass); /* * RETURN VALUES: From 8ca8e0efad5ff6303ef9d56df081d80761e2d0d7 Mon Sep 17 00:00:00 2001 From: v0-e Date: Sun, 21 Jan 2024 21:28:19 +0000 Subject: [PATCH 2/5] Default class syntax add check --- libasn1fix/asn1fix_cws.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libasn1fix/asn1fix_cws.c b/libasn1fix/asn1fix_cws.c index a026b5c83..fe8de7143 100644 --- a/libasn1fix/asn1fix_cws.c +++ b/libasn1fix/asn1fix_cws.c @@ -298,8 +298,6 @@ asn1f_parse_class_object(arg_t *arg) { #define SKIPSPACES \ for(; buf < bend && isspace(*buf); buf++) -#define SKIPSPACES_AND_COMMA \ - for(; buf < bend && (isspace(*buf) || *buf==','); buf++) static int _asn1f_parse_class_object_data_default_syntx(arg_t *arg, asn1p_expr_t *eclass, @@ -317,6 +315,10 @@ _asn1f_parse_class_object_data_default_syntx(arg_t *arg, asn1p_expr_t *eclass, asn1p_expr_t* cm; SKIPSPACES; for (; buf < bend; ++buf) { + /* find possible literal PrimitiveFieldName */ + if(*buf != '&') { + continue; + } TQ_FOR(cm, &(eclass->members), next) { /* PrimitiveFieldName */ int id_len = strlen(cm->Identifier); @@ -344,7 +346,7 @@ _asn1f_parse_class_object_data_default_syntx(arg_t *arg, asn1p_expr_t *eclass, ret = _asn1f_assign_cell_value(arg, cell, buf, p, counter); if(ret) return ret; buf = p; - SKIPSPACES_AND_COMMA; + SKIPSPACES; if(newpos) *newpos = buf; break; From 9f78ca651679238cf368195961a8c11d504a58cb Mon Sep 17 00:00:00 2001 From: v0-e Date: Mon, 22 Jan 2024 10:29:51 +0000 Subject: [PATCH 3/5] Default class syntax test 164 --- .../164-class-default-syntax-OK.asn1 | 40 +++++++++++++++++++ tests/tests-c-compiler/Makefile.am | 1 + tests/tests-c-compiler/check-src/check-164.c | 33 +++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 tests/tests-asn1c-compiler/164-class-default-syntax-OK.asn1 create mode 100644 tests/tests-c-compiler/check-src/check-164.c diff --git a/tests/tests-asn1c-compiler/164-class-default-syntax-OK.asn1 b/tests/tests-asn1c-compiler/164-class-default-syntax-OK.asn1 new file mode 100644 index 000000000..88ff9ae7c --- /dev/null +++ b/tests/tests-asn1c-compiler/164-class-default-syntax-OK.asn1 @@ -0,0 +1,40 @@ +-- OK: Everything is fine + +-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1) +-- .spelio.software.asn1c.test (9363.1.5.1) +-- .164 + +ModuleClassDefaultSyntax + { iso org(3) dod(6) internet (1) private(4) enterprise(1) + spelio(9363) software(1) asn1c(5) test(1) 164 } + DEFINITIONS AUTOMATIC TAGS ::= +BEGIN + +DCLASS ::= CLASS { +&id INTEGER, +&Type +} + +Ordered DCLASS ::= { +{&id 1, &Type UTF8String} | +{&id 2, &Type OCTET STRING} +} + +Unordered DCLASS ::= { +{&Type UTF8String, &id 17} | +{&id 8, &Type OCTET STRING} +} + +A ::= SEQUENCE +{ +a-Ordered-id DCLASS.&id ({Ordered}), +a-Ordered-val DCLASS.&Type ({Ordered}{@a-Ordered-id}) +} + +B ::= SEQUENCE +{ +b-Unordered-id DCLASS.&id ({Unordered}), +b-Unordered-val DCLASS.&Type ({Unordered}{@b-Unordered-id}) +} + +END diff --git a/tests/tests-c-compiler/Makefile.am b/tests/tests-c-compiler/Makefile.am index 2f725264e..026940bbf 100644 --- a/tests/tests-c-compiler/Makefile.am +++ b/tests/tests-c-compiler/Makefile.am @@ -62,6 +62,7 @@ TESTS += check-src/check-92.-findirect-choice.c TESTS += check-src/check-92.c TESTS += check-src/check-158.-fcompound-names.c TESTS += check-src/check-159.c +TESTS += check-src/check-164.c if TEST_64BIT TESTS += check-src/check64-134.-gen-UPER.c diff --git a/tests/tests-c-compiler/check-src/check-164.c b/tests/tests-c-compiler/check-src/check-164.c new file mode 100644 index 000000000..f4c0fd770 --- /dev/null +++ b/tests/tests-c-compiler/check-src/check-164.c @@ -0,0 +1,33 @@ +#undef NDEBUG +#include +#include +#include +#include +#include + +#include +#include + +int +main(int ac, char **av) { + A_t a; + B_t b; + + (void)ac; /* Unused argument */ + (void)av; /* Unused argument */ + + memset(&a, 0, sizeof(a)); + memset(&b, 0, sizeof(b)); + + /* Check existence of the following enum values */ + assert(a_Ordered_val_PR_UTF8String); + assert(a_Ordered_val_PR_OCTET_STRING); + assert(b_Unordered_val_PR_UTF8String); + assert(b_Unordered_val_PR_OCTET_STRING); + + /* + * No plans to fill it up: just checking whether it compiles or not. + */ + + return 0; +} From fe5747431bbcf6c81011b7e392f8f788a95add0a Mon Sep 17 00:00:00 2001 From: v0-e Date: Tue, 23 Jan 2024 12:50:10 +0000 Subject: [PATCH 4/5] Add missing comma to 18-class-OK.asn1 test file --- tests/tests-asn1c-compiler/18-class-OK.asn1 | 2 +- tests/tests-asn1c-compiler/18-class-OK.asn1.+-E_-F | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tests-asn1c-compiler/18-class-OK.asn1 b/tests/tests-asn1c-compiler/18-class-OK.asn1 index edae8566d..24a01a1b9 100644 --- a/tests/tests-asn1c-compiler/18-class-OK.asn1 +++ b/tests/tests-asn1c-compiler/18-class-OK.asn1 @@ -25,7 +25,7 @@ BEGIN operator-plus FUNCTION ::= { &ArgType Pair, - &SupportedArguments { PosPair | NegPair } + &SupportedArguments { PosPair | NegPair }, &ResultType INTEGER, &result-if-error 0, &code 1 diff --git a/tests/tests-asn1c-compiler/18-class-OK.asn1.+-E_-F b/tests/tests-asn1c-compiler/18-class-OK.asn1.+-E_-F index e5ce9c2c0..520e218be 100644 --- a/tests/tests-asn1c-compiler/18-class-OK.asn1.+-E_-F +++ b/tests/tests-asn1c-compiler/18-class-OK.asn1.+-E_-F @@ -17,7 +17,7 @@ FUNCTION ::= CLASS { operator-plus FUNCTION ::= { &ArgType Pair, - &SupportedArguments { PosPair | NegPair } + &SupportedArguments { PosPair | NegPair }, &ResultType INTEGER, &result-if-error 0, &code 1 From a7d324900c6a8702017895fd18e56cb1e9f9b854 Mon Sep 17 00:00:00 2001 From: v0-e Date: Tue, 30 Jan 2024 11:58:33 +0000 Subject: [PATCH 5/5] Remove currently not supported class fields in test file 18-class-OK --- tests/tests-asn1c-compiler/18-class-OK.asn1 | 4 ---- tests/tests-asn1c-compiler/18-class-OK.asn1.+-E_-F | 4 ---- 2 files changed, 8 deletions(-) diff --git a/tests/tests-asn1c-compiler/18-class-OK.asn1 b/tests/tests-asn1c-compiler/18-class-OK.asn1 index 24a01a1b9..c50130dcf 100644 --- a/tests/tests-asn1c-compiler/18-class-OK.asn1 +++ b/tests/tests-asn1c-compiler/18-class-OK.asn1 @@ -17,17 +17,13 @@ BEGIN &code INTEGER (0..MAX) UNIQUE, &Alphabet IA5String DEFAULT {AlphaNumeric}, &ArgType , - &SupportedArguments &ArgType OPTIONAL, &ResultType DEFAULT NULL, - &result-if-error &ResultType DEFAULT NULL, &associated-function FUNCTION OPTIONAL } operator-plus FUNCTION ::= { &ArgType Pair, - &SupportedArguments { PosPair | NegPair }, &ResultType INTEGER, - &result-if-error 0, &code 1 } diff --git a/tests/tests-asn1c-compiler/18-class-OK.asn1.+-E_-F b/tests/tests-asn1c-compiler/18-class-OK.asn1.+-E_-F index 520e218be..19b5bfe58 100644 --- a/tests/tests-asn1c-compiler/18-class-OK.asn1.+-E_-F +++ b/tests/tests-asn1c-compiler/18-class-OK.asn1.+-E_-F @@ -9,17 +9,13 @@ FUNCTION ::= CLASS { &code INTEGER (0..MAX) UNIQUE, &Alphabet IA5String DEFAULT {AlphaNumeric}, &ArgType , - &SupportedArguments &ArgType OPTIONAL, &ResultType DEFAULT NULL, - &result-if-error &ResultType DEFAULT NULL, &associated-function FUNCTION OPTIONAL } operator-plus FUNCTION ::= { &ArgType Pair, - &SupportedArguments { PosPair | NegPair }, &ResultType INTEGER, - &result-if-error 0, &code 1 }