Commit ffe79f44 authored by Lev Walkin's avatar Lev Walkin
Browse files

Enumeration constraints relaxed

parent a6dd57a9
......@@ -7,6 +7,7 @@
* Added -fincludes-quoted to asn1c to generate #includes in "double"
instead of <angle> quotes.
* PER encoding correctness fix. Reported by Grzegorz Aksamit.
* ENUMERATED extension values check relaxed. Reported by Gabriel Burca.
0.9.22: 2008-Nov-19
......
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include "Enum2.h"
#include "xer_decoder.h"
static char buf[4096];
static int buf_offset;
static int
buf_writer(const void *buffer, size_t size, void *app_key) {
char *b, *bend;
(void)app_key;
assert(buf_offset + size < sizeof(buf));
memcpy(buf + buf_offset, buffer, size);
b = buf + buf_offset;
bend = b + size;
buf_offset += size;
return 0;
}
static void
check_xer(e_Enum2 eval, char *xer_string) {
asn_dec_rval_t rv;
char buf2[128];
Enum2_t *e = 0;
long val;
rv = xer_decode(0, &asn_DEF_Enum2, (void **)&e,
xer_string, strlen(xer_string));
assert(rv.code == RC_OK);
assert(rv.consumed == strlen(xer_string));
asn_INTEGER2long(e, &val);
printf("%s -> %ld == %d\n", xer_string, val, eval);
assert(val == eval);
buf_offset = 0;
xer_encode(&asn_DEF_Enum2, e, XER_F_CANONICAL, buf_writer, 0);
buf[buf_offset] = 0;
sprintf(buf2, "<Enum2>%s</Enum2>", xer_string);
printf("%ld -> %s == %s\n", eval, buf, buf2);
assert(0 == strcmp(buf, buf2));
}
int
main() {
check_xer(Enum2_red, "<red/>");
check_xer(Enum2_green, "<green/>");
check_xer(Enum2_blue, "<blue/>");
check_xer(Enum2_orange, "<orange/>");
check_xer(Enum2_alpha, "<alpha/>");
check_xer(Enum2_beta, "<beta/>");
check_xer(Enum2_gamma, "<gamma/>");
return 0;
}
......@@ -8,15 +8,27 @@ asn1f_fix_enum(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *ev;
asn1c_integer_t max_value = -1;
asn1c_integer_t max_value_ext = -1;
int rvalue = 0;
asn1p_expr_t *ext_marker = NULL; /* "..." position */
int ret;
/* Keep track of value collisions */
asn1c_integer_t *used_vals;
int used_vals_sz = 50;
int used_vals_next = 0;
if(expr->expr_type != ASN_BASIC_ENUMERATED)
return 0; /* Just ignore it */
DEBUG("(%s)", expr->Identifier);
used_vals = (asn1c_integer_t *) malloc(sizeof(asn1c_integer_t) * used_vals_sz);
if (!used_vals) {
FATAL("Out of memory");
return -1;
}
/*
* 1. Scan the enumeration values in search for inconsistencies.
*/
......@@ -93,12 +105,16 @@ asn1f_fix_enum(arg_t *arg) {
/*
* 1.3 Check the applicability of this value.
*/
if(eval <= max_value) {
if(ext_marker) {
/*
* Enumeration is allowed to be unordered
* before the first marker.
*/
/*
* Enumeration is allowed to be unordered
* before the first marker, but after the marker
* the values must be ordered.
*/
if (ext_marker) {
if (eval > max_value_ext) {
max_value_ext = eval;
} else {
FATAL(
"Enumeration %s at line %d: "
"Explicit value \"%s(%" PRIdASN ")\" "
......@@ -108,21 +124,59 @@ asn1f_fix_enum(arg_t *arg) {
ev->_lineno,
ev->Identifier,
eval,
max_value);
max_value_ext);
rvalue = -1;
}
} else if(eval > max_value) {
}
if (eval > max_value) {
max_value = eval;
}
/*
* 1.4 Check that all identifiers are unique
*/
int unique = 1;
int uv_idx;
for (uv_idx = 0; uv_idx < used_vals_next; uv_idx++) {
if (used_vals[uv_idx] == eval) {
FATAL(
"Enumeration %s at line %d: "
"Explicit value \"%s(%" PRIdASN ")\" "
"collides with previous values",
expr->Identifier,
ev->_lineno,
ev->Identifier,
eval);
rvalue = -1;
unique = 0;
}
}
if (unique) {
/* Grow the array if needed */
if (used_vals_next >= used_vals_sz) {
asn1c_integer_t *temp;
int new_sz = used_vals_sz + 50;
temp = (asn1c_integer_t *) realloc(used_vals,
sizeof(asn1c_integer_t) * new_sz);
if (!temp) return -1;
used_vals = temp;
used_vals_sz = new_sz;
}
used_vals[used_vals_next++] = eval;
}
/*
* 1.4 Check that all identifiers before the current one
* 1.5 Check that all identifiers before the current one
* differs from it.
*/
ret = asn1f_check_unique_expr_child(arg, ev, 0, "identifier");
RET2RVAL(ret, rvalue);
}
free(used_vals);
/*
* 2. Reorder the first half (before optional "...") of the
......
......@@ -19,4 +19,19 @@ BEGIN
... -- extensible --
}
Enum2 ::= ENUMERATED
{ red, -- will be 0 --
green, -- will be 1 --
blue(45),
orange(23), -- Does not have to be ordered --
alpha,
..., -- extensible --
beta(12), -- May be less than the max value in the root --
gamma(103) -- Must be ordered --
}
Enum3 ::= ENUMERATED { a, b(3), ..., c(1) }
Enum4 ::= ENUMERATED { a, b, ..., c(3), d }
Enum5 ::= ENUMERATED { a, z(25), ..., d }
END
ModuleTestEnum1 { iso org(3) dod(6) internet(1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 3 }
DEFINITIONS ::=
BEGIN
Enum1 ::= ENUMERATED {
red(0),
green(1),
blue(4),
alpha(5),
...
}
Enum2 ::= ENUMERATED {
red(0),
green(1),
blue(45),
orange(23),
alpha(46),
...,
beta(12),
gamma(103)
}
Enum3 ::= ENUMERATED {
a(0),
b(3),
...,
c(1)
}
Enum4 ::= ENUMERATED {
a(0),
b(1),
...,
c(3),
d(4)
}
Enum5 ::= ENUMERATED {
a(0),
z(25),
...,
d(26)
}
END
This diff is collapsed.
-- SE: Semantic error
-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
-- .spelio.software.asn1c.test (9363.1.5.1)
-- .128
ModuleTestEnum1
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 128 }
DEFINITIONS ::=
BEGIN
A ::= ENUMERATED {a, b, ..., c, d(2)}
END
-- OK: Everything is fine
-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
-- .spelio.software.asn1c.test (9363.1.5.1)
-- .129
ModuleTestEnum1
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 129 }
DEFINITIONS ::=
BEGIN
A ::= ENUMERATED {a(-5), b(-4), c}
END
ModuleTestEnum1 { iso org(3) dod(6) internet(1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 129 }
DEFINITIONS ::=
BEGIN
A ::= ENUMERATED {
a(-5),
b(-4),
c(0)
}
END
-- SE: Semantic error
-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
-- .spelio.software.asn1c.test (9363.1.5.1)
-- .129
ModuleTestEnum1
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 129 }
DEFINITIONS ::=
BEGIN
A ::= ENUMERATED {a, b, ..., c, d(2)}
END
-- OK: Everything is fine
-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
-- .spelio.software.asn1c.test (9363.1.5.1)
-- .130
ModuleTestEnum1
{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 130 }
DEFINITIONS ::=
BEGIN
A ::= ENUMERATED {a(-5), b(-4),..., c}
END
ModuleTestEnum1 { iso org(3) dod(6) internet(1) private(4) enterprise(1)
spelio(9363) software(1) asn1c(5) test(1) 130 }
DEFINITIONS ::=
BEGIN
A ::= ENUMERATED {
a(-5),
b(-4),
...,
c(0)
}
END
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment