asn1: Better handling of >63 named bits/ints

First, we enlarge Member's val field to int64_t.

Then we warn about skipping 2int, int2, and parse units glue for such
things with too-large members.

And we error out when generating the template for such things with
>UINT32_MAX members.

What about too-negative members?  That could be a thing for INTEGER /
ENUMERATED.  We'll look at that later.
This commit is contained in:
Nicolas Williams
2022-01-17 12:39:19 -06:00
parent bf243c1f41
commit 9fb444983e
6 changed files with 38 additions and 27 deletions

View File

@@ -782,8 +782,8 @@ define_asn1 (int level, Type *t)
fprintf (headerfile, "INTEGER {\n"); fprintf (headerfile, "INTEGER {\n");
HEIM_TAILQ_FOREACH(m, t->members, members) { HEIM_TAILQ_FOREACH(m, t->members, members) {
space (level + 1); space (level + 1);
fprintf(headerfile, "%s(%d)%s\n", m->gen_name, m->val, fprintf(headerfile, "%s(%lld)%s\n", m->gen_name,
last_member_p(m)); (long long)m->val, last_member_p(m));
} }
space(level); space(level);
fprintf (headerfile, "}"); fprintf (headerfile, "}");
@@ -806,8 +806,8 @@ define_asn1 (int level, Type *t)
fprintf (headerfile, "ENUMERATED {\n"); fprintf (headerfile, "ENUMERATED {\n");
HEIM_TAILQ_FOREACH(m, t->members, members) { HEIM_TAILQ_FOREACH(m, t->members, members) {
space(level + 1); space(level + 1);
fprintf (headerfile, "%s(%d)%s\n", m->name, m->val, fprintf(headerfile, "%s(%lld)%s\n", m->name,
last_member_p(m)); (long long)m->val, last_member_p(m));
} }
space(level); space(level);
fprintf (headerfile, "}"); fprintf (headerfile, "}");
@@ -1200,12 +1200,12 @@ define_type(int level, const char *name, const char *basename, Type *pt, Type *t
"\"members\":[\n"); "\"members\":[\n");
HEIM_TAILQ_FOREACH(m, t->members, members) { HEIM_TAILQ_FOREACH(m, t->members, members) {
space (level + 1); space (level + 1);
fprintf(headerfile, "%s%s%s = %d%s\n", fprintf(headerfile, "%s%s%s = %lld%s\n",
label_prefix, label_prefix_sep, label_prefix, label_prefix_sep,
m->gen_name, m->val, last_member_p(m)); m->gen_name, (long long)m->val, last_member_p(m));
fprintf(jsonfile, "{\"%s%s%s\":%d}%s\n", fprintf(jsonfile, "{\"%s%s%s\":%lld}%s\n",
label_prefix, label_prefix_sep, label_prefix, label_prefix_sep,
m->gen_name, m->val, last_member_p(m)); m->gen_name, (long long)m->val, last_member_p(m));
} }
fprintf(headerfile, "} %s;\n", name); fprintf(headerfile, "} %s;\n", name);
fprintf(jsonfile, "]"); fprintf(jsonfile, "]");
@@ -1278,7 +1278,7 @@ define_type(int level, const char *name, const char *basename, Type *pt, Type *t
fprintf (headerfile, "heim_bit_string %s;\n", name); fprintf (headerfile, "heim_bit_string %s;\n", name);
fprintf(jsonfile, "\"ctype\":\"heim_bit_string\""); fprintf(jsonfile, "\"ctype\":\"heim_bit_string\"");
} else { } else {
int pos = 0; int64_t pos = 0;
getnewbasename(&newbasename, typedefp || level == 0, basename, name); getnewbasename(&newbasename, typedefp || level == 0, basename, name);
fprintf (headerfile, "struct %s {\n", newbasename); fprintf (headerfile, "struct %s {\n", newbasename);
@@ -1291,7 +1291,8 @@ define_type(int level, const char *name, const char *basename, Type *pt, Type *t
* forces the compiler to give us an obvious layout) * forces the compiler to give us an obvious layout)
*/ */
while (pos < m->val) { while (pos < m->val) {
if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL) if (asprintf (&n, "_unused%lld:1", (long long)pos) < 0 ||
n == NULL)
err(1, "malloc"); err(1, "malloc");
define_type(level + 1, n, newbasename, NULL, &i, FALSE, FALSE); define_type(level + 1, n, newbasename, NULL, &i, FALSE, FALSE);
fprintf(jsonfile, ","); fprintf(jsonfile, ",");
@@ -1318,7 +1319,8 @@ define_type(int level, const char *name, const char *basename, Type *pt, Type *t
fprintf(jsonfile, ","); fprintf(jsonfile, ",");
while (pos < bitset_size) { while (pos < bitset_size) {
char *n = NULL; char *n = NULL;
if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL) if (asprintf (&n, "_unused%lld:1", (long long)pos) < 0 ||
n == NULL)
errx(1, "malloc"); errx(1, "malloc");
define_type(level + 1, n, newbasename, NULL, &i, FALSE, FALSE); define_type(level + 1, n, newbasename, NULL, &i, FALSE, FALSE);
fprintf(jsonfile, "%s", (pos + 1) < bitset_size ? "," : ""); fprintf(jsonfile, "%s", (pos + 1) < bitset_size ? "," : "");
@@ -1349,12 +1351,12 @@ define_type(int level, const char *name, const char *basename, Type *pt, Type *t
if (m->ellipsis) { if (m->ellipsis) {
fprintf (headerfile, "/* ... */\n"); fprintf (headerfile, "/* ... */\n");
} else { } else {
fprintf(headerfile, "%s%s%s = %d%s\n", fprintf(headerfile, "%s%s%s = %lld%s\n",
label_prefix, label_prefix_sep, label_prefix, label_prefix_sep,
m->gen_name, m->val, last_member_p(m)); m->gen_name, (long long)m->val, last_member_p(m));
fprintf(jsonfile, "{\"%s%s%s\":%d%s}\n", fprintf(jsonfile, "{\"%s%s%s\":%lld%s}\n",
label_prefix, label_prefix_sep, label_prefix, label_prefix_sep,
m->gen_name, m->val, last_member_p(m)); m->gen_name, (long long)m->val, last_member_p(m));
} }
} }
space(level); space(level);

View File

@@ -328,9 +328,9 @@ decode_type(const char *name, const Type *t, int optional, struct value *defval,
"if (len < 1) break;\n"); "if (len < 1) break;\n");
pos += 8; pos += 8;
} }
fprintf (codefile, fprintf(codefile,
"(%s)->%s = (*p >> %d) & 1;\n", "(%s)->%s = (*p >> %d) & 1;\n",
name, m->gen_name, 7 - m->val % 8); name, m->gen_name, (int)(7 - m->val % 8));
} }
fprintf(codefile, fprintf(codefile,
"} while(0);\n"); "} while(0);\n");

View File

@@ -226,7 +226,7 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
fprintf (codefile, fprintf (codefile,
"if((%s)->%s) {\n" "if((%s)->%s) {\n"
"c |= 1<<%d;\n", "c |= 1<<%d;\n",
name, m->gen_name, 7 - m->val % 8); name, m->gen_name, (int)(7 - m->val % 8));
fprintf (codefile, fprintf (codefile,
"}\n"); "}\n");
} }

View File

@@ -62,7 +62,7 @@ generate_2int (const Type *t, const char *gen_name)
HEIM_TAILQ_FOREACH(m, t->members, members) { HEIM_TAILQ_FOREACH(m, t->members, members) {
fprintf (get_code_file(), "if(f.%s) r |= (1ULL << %d);\n", fprintf (get_code_file(), "if(f.%s) r |= (1ULL << %d);\n",
m->gen_name, m->val); m->gen_name, (int)m->val);
} }
fprintf (get_code_file(), "return r;\n" fprintf (get_code_file(), "return r;\n"
"}\n\n"); "}\n\n");
@@ -87,7 +87,7 @@ generate_int2 (const Type *t, const char *gen_name)
if(t->members) { if(t->members) {
HEIM_TAILQ_FOREACH(m, t->members, members) { HEIM_TAILQ_FOREACH(m, t->members, members) {
fprintf (get_code_file(), "\tflags.%s = (n >> %d) & 1;\n", fprintf (get_code_file(), "\tflags.%s = (n >> %d) & 1;\n",
m->gen_name, m->val); m->gen_name, (int)m->val);
} }
} }
fprintf (get_code_file(), "\treturn flags;\n" fprintf (get_code_file(), "\treturn flags;\n"
@@ -114,7 +114,7 @@ generate_units (const Type *t, const char *gen_name)
if(t->members) { if(t->members) {
HEIM_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) { HEIM_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
fprintf (get_code_file(), fprintf (get_code_file(),
"\t{\"%s\",\t1ULL << %d},\n", m->name, m->val); "\t{\"%s\",\t1ULL << %d},\n", m->name, (int)m->val);
} }
} }
@@ -144,8 +144,11 @@ generate_glue (const Type *t, const char *gen_name)
if (HEIM_TAILQ_EMPTY(t->members)) if (HEIM_TAILQ_EMPTY(t->members))
break; break;
HEIM_TAILQ_FOREACH(m, t->members, members) { HEIM_TAILQ_FOREACH(m, t->members, members) {
if (m->val > 63) if (m->val > 63) {
warnx("Not generating 2int, int2, or units for %s due to "
"having a member valued more than 63", gen_name);
return; return;
}
} }
generate_2int (t, gen_name); generate_2int (t, gen_name);
generate_int2 (t, gen_name); generate_int2 (t, gen_name);

View File

@@ -962,9 +962,12 @@ template_members(struct templatehead *temp,
*/ */
HEIM_TAILQ_FOREACH(m, t->members, members) { HEIM_TAILQ_FOREACH(m, t->members, members) {
if (m->val > UINT32_MAX) if (m->val > UINT32_MAX)
continue; /* Wouldn't fit in the offset field */ errx(1, "Cannot handle %s type %s with named bit %s "
"larger than 63",
t->type == TEnumerated ? "ENUMERATED" : "INTEGER",
name, m->gen_name);
add_line(&tl->template, add_line(&tl->template,
"{ A1_OP_NAME, %d, \"%s\" }", m->val, m->name); "{ A1_OP_NAME, %d, \"%s\" }", (int)m->val, m->name);
nmemb++; nmemb++;
} }
tlist_header(tl, "{ 0, 0, ((void *)(uintptr_t)%lu) }", nmemb); tlist_header(tl, "{ 0, 0, ((void *)(uintptr_t)%lu) }", nmemb);
@@ -1041,7 +1044,10 @@ template_members(struct templatehead *temp,
output_name(bname); output_name(bname);
HEIM_TAILQ_FOREACH(m, t->members, members) { HEIM_TAILQ_FOREACH(m, t->members, members) {
add_line(&template, "{ 0, %d, \"%s\" }", m->val, m->gen_name); if (m->val > UINT32_MAX)
errx(1, "Cannot handle BIT STRING type %s with named bit %s "
"larger than 63", name, m->gen_name);
add_line(&template, "{ 0, %d, \"%s\" }", (int)m->val, m->gen_name);
} }
HEIM_TAILQ_FOREACH(q, &template, members) { HEIM_TAILQ_FOREACH(q, &template, members) {

View File

@@ -91,7 +91,7 @@ struct member {
char *name; char *name;
char *gen_name; char *gen_name;
char *label; char *label;
int val; int64_t val;
int optional; int optional;
int ellipsis; int ellipsis;
struct type *type; struct type *type;