From: Alan T. DeKok Date: Fri, 6 Feb 2026 21:03:14 +0000 (-0500) Subject: fix and re-enable dictionary parsing tests X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b29a54956f482f03c900365a8182abceb7431ba4;p=thirdparty%2Ffreeradius-server.git fix and re-enable dictionary parsing tests --- diff --git a/src/lib/util/dict.h b/src/lib/util/dict.h index 9c65d5cc39c..ffa98e7f46e 100644 --- a/src/lib/util/dict.h +++ b/src/lib/util/dict.h @@ -982,7 +982,7 @@ fr_dict_t const *fr_dict_internal(void); */ void dict_dctx_debug(dict_tokenize_ctx_t *dctx); -int fr_dict_parse_str(fr_dict_t *dict, char *buf, +int fr_dict_parse_str(fr_dict_t *dict, char const *str, fr_dict_attr_t const *parent); ssize_t fr_dict_valid_name(char const *name, ssize_t len); diff --git a/src/lib/util/dict_tokenize.c b/src/lib/util/dict_tokenize.c index 38e7a2a08cb..0becef09cbd 100644 --- a/src/lib/util/dict_tokenize.c +++ b/src/lib/util/dict_tokenize.c @@ -3798,22 +3798,32 @@ int fr_dict_read(fr_dict_t *dict, char const *dir, char const *filename) /* * External API for testing */ -int fr_dict_parse_str(fr_dict_t *dict, char *buf, fr_dict_attr_t const *parent) +int fr_dict_parse_str(fr_dict_t *dict, char const *input, fr_dict_attr_t const *parent) { int argc; char *argv[DICT_MAX_ARGV]; int ret; - fr_dict_attr_flags_t base_flags; + fr_dict_attr_flags_t base_flags = {}; dict_tokenize_ctx_t dctx; + char *buf; INTERNAL_IF_NULL(dict, -1); - argc = fr_dict_str_to_argv(buf, argv, DICT_MAX_ARGV); - if (argc == 0) return 0; + /* + * str_to_argv() mangles the input buffer, which messes with 'unit_test_attribute -w foo' + */ + buf = talloc_strdup(NULL, input); + argc = fr_dict_str_to_argv(buf, argv, DICT_MAX_ARGV); + if (argc == 0) { + talloc_free(buf); + return 0; + } memset(&dctx, 0, sizeof(dctx)); dctx.dict = dict; + + dctx.stack[0].da = parent; dctx.stack[0].nest = NEST_TOP; if (dict_fixup_init(NULL, &dctx.fixup) < 0) return -1; @@ -3823,6 +3833,7 @@ int fr_dict_parse_str(fr_dict_t *dict, char *buf, fr_dict_attr_t const *parent) fr_strerror_printf("VALUE needs at least 4 arguments, got %i", argc); error: TALLOC_FREE(dctx.fixup.pool); + talloc_free(buf); return -1; } @@ -3832,25 +3843,34 @@ int fr_dict_parse_str(fr_dict_t *dict, char *buf, fr_dict_attr_t const *parent) goto error; } ret = dict_read_process_value(&dctx, argv + 1, argc - 1, &base_flags); - if (ret < 0) goto error; } else if (strcasecmp(argv[0], "ATTRIBUTE") == 0) { if (parent && (parent != dict->root)) { (void) dict_dctx_push(&dctx, parent, NEST_NONE); } - memset(&base_flags, 0, sizeof(base_flags)); - ret = dict_read_process_attribute(&dctx, argv + 1, argc - 1, &base_flags); - if (ret < 0) goto error; + + } else if (strcasecmp(argv[0], "DEFINE") == 0) { + if (parent && (parent != dict->root)) { + (void) dict_dctx_push(&dctx, parent, NEST_NONE); + } + + ret = dict_read_process_define(&dctx, + argv + 1, argc - 1, &base_flags); + } else if (strcasecmp(argv[0], "VENDOR") == 0) { ret = dict_read_process_vendor(&dctx, argv + 1, argc - 1, &base_flags); - if (ret < 0) goto error; + } else { fr_strerror_printf("Invalid input '%s'", argv[0]); goto error; } + if (ret < 0) goto error; + + talloc_free(buf); + return dict_finalise(&dctx); } diff --git a/src/tests/unit/dict.txt.broken b/src/tests/unit/dict.txt similarity index 52% rename from src/tests/unit/dict.txt.broken rename to src/tests/unit/dict.txt index caf46a81faf..75025c9dc11 100644 --- a/src/tests/unit/dict.txt.broken +++ b/src/tests/unit/dict.txt @@ -1,4 +1,6 @@ -dictionary-load radius +proto radius +proto-dictionary radius +load-dictionary protocols/radius/dictionary.test # # Tests for dictionaries @@ -8,30 +10,30 @@ dictionary-load radius # VALUEs # dictionary VALUE Unit-Enumv Foo bar -match Invalid VALUE for ATTRIBUTE "Unit-Enumv": Invalid integer value "bar" +match Failed parsing string as type 'uint32': Invalid VALUE 'bar' for attribute 'Unit-Enumv' of data type 'uint32' dictionary VALUE Unit-Byte TooBig 256 -match Invalid VALUE for ATTRIBUTE "Unit-Byte": Value 256 is invalid for type uint8 (must be in range 0-255) +match integer overflow: Invalid VALUE '256' for attribute 'Unit-Byte' of data type 'uint8' dictionary VALUE Unit-Byte Too-Small -1 -match Invalid VALUE for ATTRIBUTE "Unit-Byte": Value 18446744073709551615 is invalid for type uint8 (must be in range 0-255) +match integer underflow: Invalid VALUE '-1' for attribute 'Unit-Byte' of data type 'uint8' dictionary VALUE Unit-Short Too-Big 65537 -match Invalid VALUE for ATTRIBUTE "Unit-Short": Value 65537 is invalid for type uint16 (must be in range 0-65535) +match integer overflow: Invalid VALUE '65537' for attribute 'Unit-Short' of data type 'uint16' # Check non-uint32 types dictionary VALUE Unit-Integer64 OK 1 match ok dictionary VALUE Unit-Octets Porridge 1 -match ok +match Attribute 'Unit-Octets' does not exist in dictionary "RADIUS" dictionary VALUE Unit-Byte Life 42 match ok # re-defining it is not OK dictionary VALUE Unit-Byte Life 43 -match Duplicate VALUE alias "Life" for attribute "Unit-Byte". Old value was "42", new value was "43" +match Duplicate VALUE name "Life" for Attribute 'Unit-Byte'. Old value was "42", new value was "43" # @@ -41,7 +43,7 @@ dictionary ATTRIBUTE Foo match Invalid ATTRIBUTE syntax dictionary ATTRIBUTE Attr-26 26 octets -match Invalid ATTRIBUTE name +match Invalid name - 'Attr-' is an invalid name dictionary ATTRIBUTE My-Guy bob octets match Invalid ATTRIBUTE number @@ -51,13 +53,13 @@ match Invalid OID component "bob" (0) # 243.244 doesn't exist dictionary ATTRIBUTE Unit-Fail 241.243.255.1 integer -match Unknown attribute "255" in OID string "255.1" +match Unknown attribute '255' in OID string "255.1" for parent Unit-Ext-241-TLV dictionary ATTRIBUTE Unit-Array 255 octets[123458] match Invalid length for 'octets[...]' dictionary ATTRIBUTE Unit-Integer 255 integer[1] -match Only 'octets' types can have a 'length' parameter +match Attributes of type 'integer' cannot use the integer[...] syntax dictionary ATTRIBUTE Unit-$bad$stuff 255 integer match Invalid character '$' in attribute name "Unit-$bad$stuff" @@ -66,16 +68,16 @@ match Invalid character '$' in attribute name "Unit-$bad$stuff" # flags # dictionary ATTRIBUTE Unit-Array 241.254 octets[1234] -match Invalid length for 'octets[...]' +match Attributes cannot be more than 253 octets in length dictionary ATTRIBUTE Unit-Tag 241.255 integer has_tag -match Definition for 'Unit-Tag' is invalid: The 'has_tag' flag can only be used with RFC and VSA attributes +match The 'has_tag' flag can only be used with RFC and VSA attributes dictionary ATTRIBUTE Unit-Tag 255 date has_tag -match Definition for 'Unit-Tag' is invalid: The 'has_tag' flag can only be used for attributes of type 'integer' or 'string' +match The 'has_tag' flag can only be used for attributes of type 'integer' or 'string' dictionary ATTRIBUTE Unit-Tag 255 tlv encrypt=User-Password -match Definition for 'Unit-Tag' is invalid: The 'encrypt=User-Password' flag can only be used with attributes of type 'string' +match The 'encrypt=User-Password' flag can only be used with attributes of type 'string' # # structs @@ -84,10 +86,10 @@ dictionary ATTRIBUTE Unit-Struct 241.254 struct match ok dictionary ATTRIBUTE Unit-Struct-Byte 241.254.1 byte -match ok +match Member Unit-Struct-Byte of ATTRIBUTE Unit-Struct type 'struct' MUST use the "MEMBER" keyword dictionary ATTRIBUTE Unit-Struct-Octets 241.254.2 octets[2] -match ok +match Member Unit-Struct-Octets of ATTRIBUTE Unit-Struct type 'struct' MUST use the "MEMBER" keyword count -match 46 +match 49