From 7f941b220b71d82dfd79b43fd1616b9f3d0c7097 Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Fri, 26 Feb 2021 14:48:22 -0600 Subject: [PATCH] asn1: Basic validation of objects / object sets - Validate that required value fields have values specified in objects - Validate that unique value fields have unique values within any object set --- lib/asn1/README-X681.md | 6 ----- lib/asn1/asn1parse.y | 59 +++++++++++++++++++++++++++++++++++++++++ lib/asn1/gen_locl.h | 2 +- lib/asn1/gen_template.c | 4 +-- 4 files changed, 61 insertions(+), 10 deletions(-) diff --git a/lib/asn1/README-X681.md b/lib/asn1/README-X681.md index e045f0f59..396567ae7 100644 --- a/lib/asn1/README-X681.md +++ b/lib/asn1/README-X681.md @@ -743,12 +743,6 @@ For examples of X.681/X.682/X.683 usage, look at `lib/asn1/rfc2459.asn1`. ## Limitations - - Currently no effort is made to check the uniqueness of `UNIQUE` fields of - objects in object sets. - - - Currently no effort is made to check that required fields are specified in - objects. - - `AtNotation` is very limited. - Object set extensibility is not supported. diff --git a/lib/asn1/asn1parse.y b/lib/asn1/asn1parse.y index 2930d2d4b..41da0f39e 100644 --- a/lib/asn1/asn1parse.y +++ b/lib/asn1/asn1parse.y @@ -60,6 +60,7 @@ static Field *new_type_field(char *, int, Type *); static Field *new_fixed_type_value_field(char *, Type *, int, int, struct value *); static Type *parametrize_type(Type *, IOSClass *); static Type *type_from_class_field(IOSClass *, const char *); +static void validate_object_set(IOSObjectSet *); /*static Type *type_from_object(const char *, const char *);*/ static struct constraint_spec *new_constraint_spec(enum ctype); static Type *new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype); @@ -499,6 +500,7 @@ ObjectSetAssignment s->objectset = $4; s->objectset->symbol = s->objectset->symbol ? s->objectset->symbol : s; s->objectset->iosclass = $2; + validate_object_set($4); generate_template_objectset_forwards(s); } ; @@ -1906,3 +1908,60 @@ type_from_class_field(IOSClass *c, const char *n) } return NULL; } + +static void +validate_object_set(IOSObjectSet *os) +{ + IOSObject **objects; + ObjectField *of; + IOSObject *o; + Field *cf; + size_t nobjs, i; + + /* Check unique fields */ + HEIM_TAILQ_FOREACH(cf, os->iosclass->fields, fields) { + if (!cf->unique) + continue; + if (!cf->type) + errx(1, "Type fields of classes can't be UNIQUE (%s)", + os->iosclass->symbol->name); + sort_object_set(os, cf, &objects, &nobjs); + for (i = 0; i < nobjs; i++) { + HEIM_TAILQ_FOREACH(of, objects[i]->objfields, objfields) { + if (strcmp(cf->name, of->name)) + continue; + if (!of->value) + errx(1, "Value not specified for required UNIQUE field %s of object %s", + cf->name, objects[i]->symbol->name); + break; + } + if (i == 0) + continue; + if (object_cmp(&objects[i - 1], &objects[i]) == 0) + errx(1, "Duplicate values of UNIQUE field %s of objects %s and %s", + cf->name, objects[i - 1]->symbol->name, + objects[i]->symbol->name); + } + free(objects); + } + + /* Check required fields */ + HEIM_TAILQ_FOREACH(cf, os->iosclass->fields, fields) { + if (cf->optional || cf->defval || !cf->type) + continue; + HEIM_TAILQ_FOREACH(o, os->objects, objects) { + int specified = 0; + + HEIM_TAILQ_FOREACH(of, o->objfields, objfields) { + if (strcmp(of->name, cf->name)) + continue; + if (of->value) + specified = 1; + break; + } + if (!specified) + errx(1, "Value not specified for required non-UNIQUE field %s of object %s", + cf->name, o->symbol->name); + } + } +} diff --git a/lib/asn1/gen_locl.h b/lib/asn1/gen_locl.h index 5eccd0b07..aaed75a70 100644 --- a/lib/asn1/gen_locl.h +++ b/lib/asn1/gen_locl.h @@ -148,7 +148,7 @@ void close_codefile(void); void get_open_type_defn_fields(const Type *, Member **, Member **, Field **, Field **, int *); void sort_object_set(IOSObjectSet *, Field *, IOSObject ***, size_t *); - +int object_cmp(const void *, const void *); int is_template_compat (const Symbol *); void generate_template(const Symbol *); diff --git a/lib/asn1/gen_template.c b/lib/asn1/gen_template.c index be1dc6ff9..23e8d7e51 100644 --- a/lib/asn1/gen_template.c +++ b/lib/asn1/gen_template.c @@ -689,7 +689,7 @@ objid_cmp(struct objid *oida, struct objid *oidb) return -1; } -static int +int object_cmp(const void *va, const void *vb) { const IOSObject *oa = *(const IOSObject * const *)va; @@ -727,8 +727,6 @@ sort_object_set(IOSObjectSet *os, /* Object set to sort fields of */ IOSObject *o; size_t i, nobjs = 0; - /* FIXME: This would be a good place to check field UNIQUE constraints */ - HEIM_TAILQ_FOREACH(o, os->objects, objects) { ObjectField *typeidobjf = NULL; ObjectField *of;