asn1: Allow CHOICEs to be decorated too

Prior to this commit only those C structs for SET and SEQUENCE types
could be decorated.  Now those for CHOICE types also can be decorated.

We could further extend this to SET OF and SEQUENCE OF types if it
proves useful.
This commit is contained in:
Nicolas Williams
2022-01-15 21:07:10 -06:00
parent 1685c34b0d
commit a31db2af0d
7 changed files with 259 additions and 77 deletions

View File

@@ -1047,6 +1047,9 @@ test_decorated(void)
memset(&td, 0, sizeof(td));
memset(&tnd, 0, sizeof(tnd));
my_copy_vers_called = 0;
my_free_vers_called = 0;
td.version = 3;
td.version3.v = 5;
td.privthing = &td;
@@ -1085,7 +1088,8 @@ test_decorated(void)
warnx("copy_TESTDecorated() did not work correctly (2)");
return 1;
}
if (td.version3.v != td_copy.version3.v) {
if (td.version3.v != td_copy.version3.v ||
my_copy_vers_called != 1) {
warnx("copy_TESTDecorated() did not work correctly (3)");
return 1;
}
@@ -1119,6 +1123,97 @@ test_decorated(void)
return 0;
}
static int
test_decorated_choice(void)
{
TESTNotDecoratedChoice tndc;
TESTDecoratedChoice tdc, tdc_copy;
size_t len, size;
void *ptr;
int ret;
memset(&tdc, 0, sizeof(tdc));
memset(&tndc, 0, sizeof(tndc));
my_copy_vers_called = 0;
my_free_vers_called = 0;
tdc.element = choice_TESTDecoratedChoice_version;
tdc.u.version = 3;
tdc.version3.v = 5;
tdc.privthing = &tdc;
tdc.privobj = heim_string_create("foo");
if ((tdc.version2 = malloc(sizeof(*tdc.version2))) == NULL)
errx(1, "out of memory");
*tdc.version2 = 5;
ASN1_MALLOC_ENCODE(TESTDecoratedChoice, ptr, len, &tdc, &size, ret);
if (ret) {
warnx("could not encode a TESTDecoratedChoice struct");
return 1;
}
ret = decode_TESTNotDecoratedChoice(ptr, len, &tndc, &size);
if (ret) {
warnx("could not decode a TESTDecoratedChoice struct as TESTNotDecoratedChoice");
return 1;
}
free(ptr);
if (size != len) {
warnx("TESTDecoratedChoice encoded size mismatch");
return 1;
}
if ((int)tdc.element != (int)tndc.element ||
tdc.u.version != tndc.u.version) {
warnx("TESTDecoratedChoice did not decode as a TESTNotDecoratedChoice correctly");
return 1;
}
if (copy_TESTDecoratedChoice(&tdc, &tdc_copy)) {
warnx("copy_TESTDecoratedChoice() failed");
return 1;
}
if ((int)tdc.element != (int)tdc_copy.element ||
tdc.u.version != tdc_copy.u.version) {
warnx("copy_TESTDecoratedChoice() did not work correctly (1)");
return 1;
}
if (tdc_copy.version2 == NULL || *tdc.version2 != *tdc_copy.version2) {
warnx("copy_TESTDecoratedChoice() did not work correctly (2)");
return 1;
}
if (tdc.version3.v != tdc_copy.version3.v ||
my_copy_vers_called != 1) {
warnx("copy_TESTDecoratedChoice() did not work correctly (3)");
return 1;
}
if (tdc_copy.privthing != 0) {
warnx("copy_TESTDecoratedChoice() did not work correctly (4)");
return 1;
}
if (tdc_copy.privobj != tdc.privobj) {
warnx("copy_TESTDecoratedChoice() did not work correctly (5)");
return 1;
}
free_TESTDecoratedChoice(&tdc_copy);
free_TESTDecoratedChoice(&tdc);
if (tdc.version2) {
warnx("free_TESTDecoratedChoice() did not work correctly (1)");
return 1;
}
if (tdc.version3.v != 0 || my_free_vers_called != 2) {
warnx("free_TESTDecoratedChoice() did not work correctly (2)");
return 1;
}
if (tdc.privthing != 0) {
warnx("free_TESTDecoratedChoice() did not work correctly (3)");
return 1;
}
if (tdc.privobj != 0) {
warnx("free_TESTDecoratedChoice() did not work correctly (4)");
return 1;
}
return 0;
}
static int
cmp_TESTImplicit (void *a, void *b)
@@ -2597,6 +2692,7 @@ main(int argc, char **argv)
DO_ONE(test_default);
DO_ONE(test_decorated_choice);
DO_ONE(test_decorated);
#if ASN1_IOS_SUPPORTED