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");
HEIM_TAILQ_FOREACH(m, t->members, members) {
space (level + 1);
fprintf(headerfile, "%s(%d)%s\n", m->gen_name, m->val,
last_member_p(m));
fprintf(headerfile, "%s(%lld)%s\n", m->gen_name,
(long long)m->val, last_member_p(m));
}
space(level);
fprintf (headerfile, "}");
@@ -806,8 +806,8 @@ define_asn1 (int level, Type *t)
fprintf (headerfile, "ENUMERATED {\n");
HEIM_TAILQ_FOREACH(m, t->members, members) {
space(level + 1);
fprintf (headerfile, "%s(%d)%s\n", m->name, m->val,
last_member_p(m));
fprintf(headerfile, "%s(%lld)%s\n", m->name,
(long long)m->val, last_member_p(m));
}
space(level);
fprintf (headerfile, "}");
@@ -1200,12 +1200,12 @@ define_type(int level, const char *name, const char *basename, Type *pt, Type *t
"\"members\":[\n");
HEIM_TAILQ_FOREACH(m, t->members, members) {
space (level + 1);
fprintf(headerfile, "%s%s%s = %d%s\n",
fprintf(headerfile, "%s%s%s = %lld%s\n",
label_prefix, label_prefix_sep,
m->gen_name, m->val, last_member_p(m));
fprintf(jsonfile, "{\"%s%s%s\":%d}%s\n",
m->gen_name, (long long)m->val, last_member_p(m));
fprintf(jsonfile, "{\"%s%s%s\":%lld}%s\n",
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(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(jsonfile, "\"ctype\":\"heim_bit_string\"");
} else {
int pos = 0;
int64_t pos = 0;
getnewbasename(&newbasename, typedefp || level == 0, basename, name);
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)
*/
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");
define_type(level + 1, n, newbasename, NULL, &i, FALSE, FALSE);
fprintf(jsonfile, ",");
@@ -1318,7 +1319,8 @@ define_type(int level, const char *name, const char *basename, Type *pt, Type *t
fprintf(jsonfile, ",");
while (pos < bitset_size) {
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");
define_type(level + 1, n, newbasename, NULL, &i, FALSE, FALSE);
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) {
fprintf (headerfile, "/* ... */\n");
} else {
fprintf(headerfile, "%s%s%s = %d%s\n",
fprintf(headerfile, "%s%s%s = %lld%s\n",
label_prefix, label_prefix_sep,
m->gen_name, m->val, last_member_p(m));
fprintf(jsonfile, "{\"%s%s%s\":%d%s}\n",
m->gen_name, (long long)m->val, last_member_p(m));
fprintf(jsonfile, "{\"%s%s%s\":%lld%s}\n",
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);

View File

@@ -330,7 +330,7 @@ decode_type(const char *name, const Type *t, int optional, struct value *defval,
}
fprintf(codefile,
"(%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,
"} while(0);\n");

View File

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

View File

@@ -62,7 +62,7 @@ generate_2int (const Type *t, const char *gen_name)
HEIM_TAILQ_FOREACH(m, t->members, members) {
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"
"}\n\n");
@@ -87,7 +87,7 @@ generate_int2 (const Type *t, const char *gen_name)
if(t->members) {
HEIM_TAILQ_FOREACH(m, t->members, members) {
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"
@@ -114,7 +114,7 @@ generate_units (const Type *t, const char *gen_name)
if(t->members) {
HEIM_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
fprintf (get_code_file(),
"\t{\"%s\",\t1ULL << %d},\n", m->name, m->val);
"\t{\"%s\",\t1ULL << %d},\n", m->name, (int)m->val);
}
}
@@ -144,9 +144,12 @@ generate_glue (const Type *t, const char *gen_name)
if (HEIM_TAILQ_EMPTY(t->members))
break;
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;
}
}
generate_2int (t, gen_name);
generate_int2 (t, gen_name);
if (parse_units_flag)

View File

@@ -962,9 +962,12 @@ template_members(struct templatehead *temp,
*/
HEIM_TAILQ_FOREACH(m, t->members, members) {
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,
"{ A1_OP_NAME, %d, \"%s\" }", m->val, m->name);
"{ A1_OP_NAME, %d, \"%s\" }", (int)m->val, m->name);
nmemb++;
}
tlist_header(tl, "{ 0, 0, ((void *)(uintptr_t)%lu) }", nmemb);
@@ -1041,7 +1044,10 @@ template_members(struct templatehead *temp,
output_name(bname);
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) {

View File

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