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
This commit is contained in:
@@ -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.
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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 *);
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user