OBJECT IDENTIFIER and RELATIVE-OID API simplified
diff --git a/ChangeLog b/ChangeLog
index f45ec83..3163516 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,7 @@
NOTABLE:
* converter-sample.c renamed into converter-example.c.
+ * OBJECT IDENTIFIER and RELATIVE-OID API simplified.
* Added random value generation (-R option to converter-example).
* Added LibFuzzer-based randomized tests for supported transfer syntaxes
(DER, OER, UPER, XER) into tests/tests-randomized. See the following
diff --git a/asn1c/unber.c b/asn1c/unber.c
index 1a33b4d..b2fec49 100644
--- a/asn1c/unber.c
+++ b/asn1c/unber.c
@@ -434,7 +434,7 @@
static int
print_V(const char *fname, FILE *fp, ber_tlv_tag_t tlv_tag,
ber_tlv_len_t tlv_len) {
- asn1c_integer_t *arcs = 0; /* Object identifier arcs */
+ asn_oid_arc_t *arcs = 0; /* Object identifier arcs */
unsigned char *vbuf = 0;
asn1p_expr_type_e etype = 0;
asn1c_integer_t collector = 0;
@@ -577,20 +577,19 @@
break;
case ASN_BASIC_OBJECT_IDENTIFIER:
if(vbuf) {
- OBJECT_IDENTIFIER_t oid;
- int arcno;
+ OBJECT_IDENTIFIER_t oid = {0, 0};
+ ssize_t arcno;
oid.buf = vbuf;
oid.size = tlv_len;
- arcno = OBJECT_IDENTIFIER_get_arcs(&oid, arcs, sizeof(*arcs),
- tlv_len + 1);
+ arcno = OBJECT_IDENTIFIER_get_arcs(&oid, arcs, tlv_len + 1);
if(arcno >= 0) {
assert(arcno <= (tlv_len + 1));
printf(" F>");
for(i = 0; i < arcno; i++) {
if(i) printf(".");
- printf("%s", asn1p_itoa(arcs[i]));
+ printf("%" PRIu32, arcs[i]);
}
FREEMEM(vbuf);
vbuf = 0;
@@ -605,13 +604,13 @@
oid.buf = vbuf;
oid.size = tlv_len;
- arcno = RELATIVE_OID_get_arcs(&oid, arcs, sizeof(*arcs), tlv_len);
+ arcno = RELATIVE_OID_get_arcs(&oid, arcs, tlv_len);
if(arcno >= 0) {
- assert(arcno <= (tlv_len + 1));
+ assert(arcno <= tlv_len);
printf(" F>");
for(i = 0; i < arcno; i++) {
if(i) printf(".");
- printf("%s", asn1p_itoa(arcs[i]));
+ printf("%" PRIu32, arcs[i]);
}
FREEMEM(vbuf);
vbuf = 0;
diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c
index 5650368..3257cf7 100644
--- a/skeletons/INTEGER.c
+++ b/skeletons/INTEGER.c
@@ -1028,9 +1028,9 @@
intmax_t value;
#define ASN1_INTMAX_MAX ((~(uintmax_t)0) >> 1)
-
const intmax_t upper_boundary = ASN1_INTMAX_MAX / 10;
intmax_t last_digit_max = ASN1_INTMAX_MAX % 10;
+#undef ASN1_INTMAX_MAX
if(str >= *end) return ASN_STRTOX_ERROR_INVAL;
@@ -1084,6 +1084,66 @@
return ASN_STRTOX_OK;
}
+/*
+ * Parse the number in the given string until the given *end position,
+ * returning the position after the last parsed character back using the
+ * same (*end) pointer.
+ * WARNING: This behavior is different from the standard strtoul/strtoumax(3).
+ */
+enum asn_strtox_result_e
+asn_strtoumax_lim(const char *str, const char **end, uintmax_t *uintp) {
+ uintmax_t value;
+
+#define ASN1_UINTMAX_MAX ((~(uintmax_t)0))
+ const uintmax_t upper_boundary = ASN1_UINTMAX_MAX / 10;
+ uintmax_t last_digit_max = ASN1_UINTMAX_MAX % 10;
+#undef ASN1_UINTMAX_MAX
+
+ if(str >= *end) return ASN_STRTOX_ERROR_INVAL;
+
+ switch(*str) {
+ case '-':
+ return ASN_STRTOX_ERROR_INVAL;
+ case '+':
+ str++;
+ if(str >= *end) {
+ *end = str;
+ return ASN_STRTOX_EXPECT_MORE;
+ }
+ }
+
+ for(value = 0; str < (*end); str++) {
+ switch(*str) {
+ case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
+ case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: {
+ unsigned int d = *str - '0';
+ if(value < upper_boundary) {
+ value = value * 10 + d;
+ } else if(value == upper_boundary) {
+ if(d <= last_digit_max) {
+ value = value * 10 + d;
+ } else {
+ *end = str;
+ return ASN_STRTOX_ERROR_RANGE;
+ }
+ } else {
+ *end = str;
+ return ASN_STRTOX_ERROR_RANGE;
+ }
+ }
+ continue;
+ default:
+ *end = str;
+ *uintp = value;
+ return ASN_STRTOX_EXTRA_DATA;
+ }
+ }
+
+ *end = str;
+ *uintp = value;
+ return ASN_STRTOX_OK;
+}
+
enum asn_strtox_result_e
asn_strtol_lim(const char *str, const char **end, long *lp) {
intmax_t value;
@@ -1114,6 +1174,36 @@
return ASN_STRTOX_ERROR_INVAL;
}
+enum asn_strtox_result_e
+asn_strtoul_lim(const char *str, const char **end, unsigned long *ulp) {
+ uintmax_t value;
+ switch(asn_strtoumax_lim(str, end, &value)) {
+ case ASN_STRTOX_ERROR_RANGE:
+ return ASN_STRTOX_ERROR_RANGE;
+ case ASN_STRTOX_ERROR_INVAL:
+ return ASN_STRTOX_ERROR_INVAL;
+ case ASN_STRTOX_EXPECT_MORE:
+ return ASN_STRTOX_EXPECT_MORE;
+ case ASN_STRTOX_OK:
+ if(value <= ULONG_MAX) {
+ *ulp = value;
+ return ASN_STRTOX_OK;
+ } else {
+ return ASN_STRTOX_ERROR_RANGE;
+ }
+ case ASN_STRTOX_EXTRA_DATA:
+ if(value <= ULONG_MAX) {
+ *ulp = value;
+ return ASN_STRTOX_EXTRA_DATA;
+ } else {
+ return ASN_STRTOX_ERROR_RANGE;
+ }
+ }
+
+ assert(!"Unreachable");
+ return ASN_STRTOX_ERROR_INVAL;
+}
+
int
INTEGER_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
const void *bptr) {
diff --git a/skeletons/INTEGER.h b/skeletons/INTEGER.h
index 70d6a3c..708d845 100644
--- a/skeletons/INTEGER.h
+++ b/skeletons/INTEGER.h
@@ -83,8 +83,14 @@
ASN_STRTOX_OK = 0, /* Conversion succeded, number ends at (*end) */
ASN_STRTOX_EXTRA_DATA = 1 /* Conversion succeded, but the string has extra stuff */
};
-enum asn_strtox_result_e asn_strtol_lim(const char *str, const char **end, long *l);
-enum asn_strtox_result_e asn_strtoimax_lim(const char *str, const char **end, intmax_t *l);
+enum asn_strtox_result_e asn_strtol_lim(const char *str, const char **end,
+ long *l);
+enum asn_strtox_result_e asn_strtoul_lim(const char *str, const char **end,
+ unsigned long *l);
+enum asn_strtox_result_e asn_strtoimax_lim(const char *str, const char **end,
+ intmax_t *l);
+enum asn_strtox_result_e asn_strtoumax_lim(const char *str, const char **end,
+ uintmax_t *l);
/*
* Convert the integer value into the corresponding enumeration map entry.
diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c
index 86fee46..73693de 100644
--- a/skeletons/OBJECT_IDENTIFIER.c
+++ b/skeletons/OBJECT_IDENTIFIER.c
@@ -55,16 +55,6 @@
0 /* No specifics */
};
-
-/*
- * Endianness check. Will be optimized out by the compiler.
- */
-static int
-little_endian() {
- int le_check = 1;
- return *(char *)&le_check;
-}
-
int
OBJECT_IDENTIFIER_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
asn_app_constraint_failed_f *ctfailcb, void *app_key) {
@@ -88,209 +78,107 @@
return 0;
}
-int
-OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, unsigned int arclen, signed int add, void *rvbufp, unsigned int rvsize) {
- const uint8_t *arcend = arcbuf + arclen; /* End of arc */
- unsigned int cache = 0; /* No more than 14 significant bits */
- unsigned char *rvbuf = (unsigned char *)rvbufp;
- unsigned char *rvstart = rvbuf; /* Original start of the value buffer */
- int inc; /* Return value growth direction */
+static ssize_t
+OBJECT_IDENTIFIER_get_first_arcs(const uint8_t *arcbuf, size_t arcbuf_len,
+ asn_oid_arc_t *arc0, asn_oid_arc_t *arc1) {
+ asn_oid_arc_t value;
- rvsize *= CHAR_BIT; /* bytes to bits */
- arclen *= 7; /* bytes to bits */
+ ssize_t rd = OBJECT_IDENTIFIER_get_single_arc(arcbuf, arcbuf_len, &value);
+ if(rd <= 0) return rd;
- assert(add <= 0);
+ if(value >= 80) {
+ *arc0 = 2;
+ *arc1 = value - 80;
+ } else if(value >= 40) {
+ *arc0 = 1;
+ *arc1 = value - 40;
+ } else {
+ *arc0 = 0;
+ *arc1 = value;
+ }
- /*
- * The arc has the number of bits
- * cannot be represented using supplied return value type.
- */
- if(arclen > rvsize) {
- if(arclen > (rvsize + CHAR_BIT)) {
- errno = ERANGE; /* Overflow */
- return -1;
- } else {
- /*
- * Even if the number of bits in the arc representation
- * is higher than the width of supplied * return value
- * type, there is still possible to fit it when there
- * are few unused high bits in the arc value
- * representaion.
- *
- * Moreover, there is a possibility that the
- * number could actually fit the arc space, given
- * that add is negative, but we don't handle
- * such "temporary lack of precision" situation here.
- * May be considered as a bug.
- */
- uint8_t mask = (0xff << (7-(arclen - rvsize))) & 0x7f;
- if((*arcbuf & mask)) {
- errno = ERANGE; /* Overflow */
- return -1;
- }
- /* Fool the routine computing unused bits */
- arclen -= 7;
- cache = *arcbuf & 0x7f;
- arcbuf++;
- }
- }
- /* Faster path for common size */
- if(rvsize == (CHAR_BIT * sizeof(unsigned long))
- && (arcend-arcbuf) <= (ssize_t)sizeof(unsigned long)) {
- unsigned long accum;
- /* Gather all bits into the accumulator */
- for(accum = cache; arcbuf < arcend; arcbuf++)
- accum = (accum << 7) | (*arcbuf & ~0x80);
- if(accum < (unsigned)-add
- || accum > ULONG_MAX-(unsigned long)(-add)) {
- errno = ERANGE; /* Overflow */
- return -1;
- }
- *(unsigned long *)(void *)rvbuf =
- accum - (unsigned long)(-add); /* alignment OK! */
- return 0;
- }
-
- if(little_endian()) { /* Little endian (x86) */
- /* "Convert" to big endian */
- rvbuf += rvsize / CHAR_BIT - 1;
- rvstart--;
- inc = -1; /* Descending */
- } else {
- inc = +1; /* Big endian */
- }
-
- {
- int bits; /* typically no more than 3-4 bits */
-
- /* Clear the high unused bits */
- for(bits = rvsize - arclen;
- bits > CHAR_BIT;
- rvbuf += inc, bits -= CHAR_BIT)
- *rvbuf = 0;
-
- /* Fill the body of a value */
- for(; arcbuf < arcend; arcbuf++) {
- cache = (cache << 7) | (*arcbuf & 0x7f);
- bits += 7;
- if(bits >= CHAR_BIT) {
- bits -= CHAR_BIT;
- *rvbuf = (cache >> bits);
- rvbuf += inc;
- }
- }
- if(bits) {
- *rvbuf = cache;
- rvbuf += inc;
- }
- }
-
- if(add) {
- for(rvbuf -= inc; rvbuf != rvstart; rvbuf -= inc) {
- int v = add + *rvbuf;
- if(v & ((unsigned)~0 << CHAR_BIT)) {
- *rvbuf = (unsigned char)(v + (1 << CHAR_BIT));
- add = -1;
- } else {
- *rvbuf = v;
- break;
- }
- }
- if(rvbuf == rvstart) {
- /* No space to carry over */
- errno = ERANGE; /* Overflow */
- return -1;
- }
- }
-
- return 0;
+ return rd;
}
ssize_t
-OBJECT_IDENTIFIER__dump_arc(const uint8_t *arcbuf, int arclen, int add,
- asn_app_consume_bytes_f *cb, void *app_key) {
- char scratch[64]; /* Conservative estimate */
- unsigned long accum; /* Bits accumulator */
- char *p; /* Position in the scratch buffer */
+OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, size_t arcbuf_len,
+ asn_oid_arc_t *ret_value) {
+ const uint8_t *b = arcbuf;
+ const uint8_t *arcend = arcbuf + arcbuf_len; /* End of arc */
- if(OBJECT_IDENTIFIER_get_single_arc(arcbuf, arclen, add,
- &accum, sizeof(accum)))
- return -1;
+ if(arcbuf == arcend) {
+ return 0;
+ } else {
+ asn_oid_arc_t accum;
+ /* Gather all bits into the accumulator */
+ for(accum = 0; b < arcend; b++) {
+ accum = (accum << 7) | (*b & ~0x80);
+ if((*b & 0x80) == 0) {
+ if(accum <= ASN_OID_ARC_MAX) {
+ *ret_value = accum;
+ return 1 + (b - arcbuf);
+ } else {
+ errno = ERANGE; /* Overflow */
+ return -1;
+ }
+ }
+ }
+ errno = EINVAL;
+ return -1;
+ }
- if(accum) {
- ssize_t len;
-
- /* Fill the scratch buffer in reverse. */
- p = scratch + sizeof(scratch);
- for(; accum; accum /= 10)
- *(--p) = (char)(accum % 10) + 0x30; /* Put a digit */
-
- len = sizeof(scratch) - (p - scratch);
- if(cb(p, len, app_key) < 0)
- return -1;
- return len;
- } else {
- *scratch = 0x30;
- if(cb(scratch, 1, app_key) < 0)
- return -1;
- return 1;
- }
-}
-
-int
-OBJECT_IDENTIFIER_print_arc(const uint8_t *arcbuf, int arclen, int add,
- asn_app_consume_bytes_f *cb, void *app_key) {
-
- if(OBJECT_IDENTIFIER__dump_arc(arcbuf, arclen, add, cb, app_key) < 0)
- return -1;
-
- return 0;
}
static ssize_t
-OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st, asn_app_consume_bytes_f *cb, void *app_key) {
- ssize_t wrote_len = 0;
- size_t startn;
- int add = 0;
- size_t i;
+OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ char scratch[32];
+ asn_oid_arc_t arc0, arc1;
+ size_t produced = 0;
+ size_t off = 0;
+ ssize_t rd;
+ int ret;
- for(i = 0, startn = 0; i < st->size; i++) {
- uint8_t b = st->buf[i];
- if((b & 0x80)) /* Continuation expected */
- continue;
+ rd = OBJECT_IDENTIFIER_get_first_arcs(st->buf, st->size, &arc0, &arc1);
+ if(rd <= 0) {
+ return -1;
+ }
- if(startn == 0) {
- /*
- * First two arcs are encoded through the backdoor.
- */
- if(i) {
- add = -80;
- if(cb("2", 1, app_key) < 0) return -1;
- } else if(b <= 39) {
- add = 0;
- if(cb("0", 1, app_key) < 0) return -1;
- } else if(b < 79) {
- add = -40;
- if(cb("1", 1, app_key) < 0) return -1;
- } else {
- add = -80;
- if(cb("2", 1, app_key) < 0) return -1;
- }
- wrote_len += 1;
- }
+ ret = snprintf(scratch, sizeof(scratch), "%"PRIu32".%"PRIu32, arc0, arc1);
+ if(ret >= (ssize_t)sizeof(scratch)) {
+ return -1;
+ }
+ produced += ret;
+ if(cb(scratch, ret, app_key) < 0)
+ return -1;
- if(cb(".", 1, app_key) < 0) /* Separate arcs */
- return -1;
+ for(off = rd; ; ) {
+ asn_oid_arc_t arc;
+ rd = OBJECT_IDENTIFIER_get_single_arc(st->buf + off, st->size - off,
+ &arc);
+ if(rd < 0) {
+ return -1;
+ } else if(rd == 0) {
+ /* No more arcs. */
+ break;
+ } else {
+ off += rd;
+ assert(off <= st->size);
+ ret = snprintf(scratch, sizeof(scratch), ".%" PRIu32, arc);
+ if(ret >= (ssize_t)sizeof(scratch)) {
+ return -1;
+ }
+ produced += ret;
+ if(cb(scratch, ret, app_key) < 0) return -1;
+ }
+ }
- add = OBJECT_IDENTIFIER__dump_arc(&st->buf[startn],
- i - startn + 1, add, cb, app_key);
- if(add < 0) return -1;
- wrote_len += 1 + add;
- startn = i + 1;
- add = 0;
- }
+ if(off != st->size) {
+ ASN_DEBUG("Could not scan to the end of Object Identifier");
+ return -1;
+ }
- return wrote_len;
+ return produced;
}
static enum xer_pbd_rval
@@ -298,38 +186,37 @@
OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr;
const char *chunk_end = (const char *)chunk_buf + chunk_size;
const char *endptr;
- long s_arcs[10];
- long *arcs = s_arcs;
- int arcs_count;
- int ret;
+ asn_oid_arc_t s_arcs[10];
+ asn_oid_arc_t *arcs = s_arcs;
+ ssize_t num_arcs;
+ ssize_t ret;
(void)td;
- arcs_count = OBJECT_IDENTIFIER_parse_arcs(
- (const char *)chunk_buf, chunk_size, arcs,
- sizeof(s_arcs)/sizeof(s_arcs[0]), &endptr);
- if(arcs_count < 0) {
+ num_arcs = OBJECT_IDENTIFIER_parse_arcs(
+ (const char *)chunk_buf, chunk_size, arcs,
+ sizeof(s_arcs) / sizeof(s_arcs[0]), &endptr);
+ if(num_arcs < 0) {
/* Expecting more than zero arcs */
return XPBD_BROKEN_ENCODING;
- } else if(arcs_count == 0) {
+ } else if(num_arcs == 0) {
return XPBD_NOT_BODY_IGNORE;
}
assert(endptr == chunk_end);
- if((size_t)arcs_count > sizeof(s_arcs)/sizeof(s_arcs[0])) {
- arcs = (long *)MALLOC(arcs_count * sizeof(long));
+ if((size_t)num_arcs > sizeof(s_arcs)/sizeof(s_arcs[0])) {
+ arcs = (asn_oid_arc_t *)MALLOC(num_arcs * sizeof(asn_oid_arc_t));
if(!arcs) return XPBD_SYSTEM_FAILURE;
- ret = OBJECT_IDENTIFIER_parse_arcs(
- (const char *)chunk_buf, chunk_size,
- arcs, arcs_count, &endptr);
- if(ret != arcs_count)
+ ret = OBJECT_IDENTIFIER_parse_arcs((const char *)chunk_buf, chunk_size,
+ arcs, num_arcs, &endptr);
+ if(ret != num_arcs)
return XPBD_SYSTEM_FAILURE; /* assert?.. */
}
/*
* Convert arcs into BER representation.
*/
- ret = OBJECT_IDENTIFIER_set_arcs(st, arcs, sizeof(*arcs), arcs_count);
+ ret = OBJECT_IDENTIFIER_set_arcs(st, arcs, num_arcs);
if(arcs != s_arcs) FREEMEM(arcs);
return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED;
@@ -352,16 +239,17 @@
const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
asn_enc_rval_t er;
- (void)ilevel;
- (void)flags;
+ (void)ilevel;
+ (void)flags;
- if(!st || !st->buf)
- ASN__ENCODE_FAILED;
+ if(!st || !st->buf) {
+ ASN__ENCODE_FAILED;
+ }
- er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key);
- if(er.encoded < 0) ASN__ENCODE_FAILED;
+ er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key);
+ if(er.encoded < 0) ASN__ENCODE_FAILED;
- ASN__ENCODED_OK(er);
+ ASN__ENCODED_OK(er);
}
int
@@ -379,293 +267,201 @@
if(cb("{ ", 2, app_key) < 0)
return -1;
- if(OBJECT_IDENTIFIER__dump_body(st, cb, app_key) < 0)
- return -1;
+ if(OBJECT_IDENTIFIER__dump_body(st, cb, app_key) < 0) {
+ return -1;
+ }
- return (cb(" }", 2, app_key) < 0) ? -1 : 0;
+ return (cb(" }", 2, app_key) < 0) ? -1 : 0;
}
-int
-OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *oid, void *arcs,
- unsigned int arc_type_size, unsigned int arc_slots) {
- void *arcs_end = (char *)arcs + (arc_type_size * arc_slots);
- int num_arcs = 0;
- int startn = 0;
- int add = 0;
- size_t i;
+ssize_t
+OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *st, asn_oid_arc_t *arcs,
+ size_t arc_slots) {
+ asn_oid_arc_t arc0, arc1;
+ size_t num_arcs = 0;
+ size_t off;
+ ssize_t rd;
- if(!oid || !oid->buf || (arc_slots && arc_type_size <= 1)) {
- errno = EINVAL;
- return -1;
- }
+ if(!st || !st->buf) {
+ errno = EINVAL;
+ return -1;
+ }
- for(i = 0; i < oid->size; i++) {
- uint8_t b = oid->buf[i];
- if((b & 0x80)) /* Continuation expected */
- continue;
+ rd = OBJECT_IDENTIFIER_get_first_arcs(st->buf, st->size, &arc0, &arc1);
+ if(rd <= 0) {
+ return -1;
+ }
+ num_arcs = 2;
+ switch(arc_slots) {
+ default:
+ case 2:
+ arcs[1] = arc1;
+ /* Fall through */
+ case 1:
+ arcs[0] = arc0;
+ /* Fall through */
+ case 0:
+ break;
+ }
- if(num_arcs == 0) {
- /*
- * First two arcs are encoded through the backdoor.
- */
- int first_arc;
- num_arcs++;
- if(!arc_slots) { num_arcs++; continue; }
+ for(off = rd; ; ) {
+ asn_oid_arc_t arc;
+ rd = OBJECT_IDENTIFIER_get_single_arc(st->buf + off, st->size - off,
+ &arc);
+ if(rd < 0) {
+ return -1;
+ } else if(rd == 0) {
+ /* No more arcs. */
+ break;
+ } else {
+ off += rd;
+ if(num_arcs < arc_slots) {
+ arcs[num_arcs] = arc;
+ }
+ num_arcs++;
+ }
+ }
- if(i) first_arc = 2;
- else if(b <= 39) first_arc = 0;
- else if(b < 79) first_arc = 1;
- else first_arc = 2;
+ if(off != st->size) {
+ return -1;
+ }
- add = -40 * first_arc;
- memset(arcs, 0, arc_type_size);
- *(unsigned char *)((char *)arcs
- + (little_endian()?0:(arc_type_size - 1)))
- = first_arc;
- arcs = ((char *)arcs) + arc_type_size;
- }
-
- /* Decode, if has space */
- if(arcs < arcs_end) {
- if(OBJECT_IDENTIFIER_get_single_arc(&oid->buf[startn],
- i - startn + 1, add,
- arcs, arc_type_size)) {
- return -1;
- }
- startn = i + 1;
- arcs = ((char *)arcs) + arc_type_size;
- add = 0;
- }
- num_arcs++;
- }
-
- return num_arcs;
+ return num_arcs;
}
/*
* Save the single value as an object identifier arc.
*/
-int
-OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, const void *arcval, unsigned int arcval_size, int prepared_order) {
- /*
+ssize_t
+OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, size_t arcbuf_len,
+ asn_oid_arc_t value) {
+ /*
* The following conditions must hold:
- * assert(arcval);
- * assert(arcval_size > 0);
- * assert(arcval_size <= 16);
* assert(arcbuf);
*/
- const uint8_t *tend, *tp;
- unsigned int cache;
- uint8_t *bp = arcbuf;
- int bits;
- uint8_t buffer[16];
+ uint8_t scratch[((sizeof(value) * CHAR_BIT + 6) / 7)];
+ uint8_t *scratch_end = &scratch[sizeof(scratch)-1];
+ uint8_t *b;
+ size_t result_len;
+ uint8_t mask;
- if(little_endian() && !prepared_order) {
- const uint8_t *a = (const unsigned char *)arcval + arcval_size - 1;
- const uint8_t *aend = (const uint8_t *)arcval;
- uint8_t *msb = buffer + arcval_size - 1;
- uint8_t *tb;
- for(tb = buffer; a >= aend; tb++, a--)
- if((*tb = *a) && (tb < msb))
- msb = tb;
- tend = &buffer[arcval_size];
- tp = msb; /* Most significant non-zero byte */
- } else {
- /* Look for most significant non-zero byte */
- tend = (const unsigned char *)arcval + arcval_size;
- for(tp = (const uint8_t *)arcval; tp < tend - 1; tp++)
- if(*tp) break;
- }
+ for(b = scratch_end, mask = 0; ; mask = 0x80, b--) {
+ *b = mask | (value & 0x7f);
+ value >>= 7;
+ if(!value) {
+ break;
+ }
+ }
- /*
- * Split the value in 7-bits chunks.
- */
- bits = ((tend - tp) * CHAR_BIT) % 7;
- if(bits) {
- cache = *tp >> (CHAR_BIT - bits);
- if(cache) {
- *bp++ = cache | 0x80;
- cache = *tp++;
- bits = CHAR_BIT - bits;
- } else {
- bits = -bits;
- }
- } else {
- cache = 0;
- }
- for(; tp < tend; tp++) {
- cache = (cache << CHAR_BIT) + *tp;
- bits += CHAR_BIT;
- while(bits >= 7) {
- bits -= 7;
- *bp++ = 0x80 | (cache >> bits);
- }
- }
- if(bits) *bp++ = cache;
- bp[-1] &= 0x7f; /* Clear the last bit */
+ result_len = (scratch_end - b) + 1;
- return bp - arcbuf;
+ if(result_len > arcbuf_len) {
+ return -1;
+ }
+
+ memcpy(arcbuf, b, result_len);
+
+ return result_len;
}
int
-OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *oid, const void *arcs, unsigned int arc_type_size, unsigned int arc_slots) {
- uint8_t *buf;
- uint8_t *bp;
- unsigned int arc0;
- unsigned int arc1;
- unsigned size;
- unsigned i;
+OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *st, const asn_oid_arc_t *arcs,
+ size_t arc_slots) {
+ uint8_t *buf;
+ uint8_t *bp;
+ size_t wrote;
+ asn_oid_arc_t arc0;
+ asn_oid_arc_t arc1;
+ size_t size;
+ size_t i;
- if(!oid || !arcs || arc_type_size < 1
- || arc_type_size > 16
- || arc_slots < 2) {
- errno = EINVAL;
+ if(!st || !arcs || arc_slots < 2) {
+ errno = EINVAL;
return -1;
}
- switch(arc_type_size) {
- case sizeof(char):
- arc0 = ((const unsigned char *)arcs)[0];
- arc1 = ((const unsigned char *)arcs)[1];
- break;
- case sizeof(short):
- arc0 = ((const unsigned short *)arcs)[0];
- arc1 = ((const unsigned short *)arcs)[1];
- break;
- case sizeof(int):
- arc0 = ((const unsigned int *)arcs)[0];
- arc1 = ((const unsigned int *)arcs)[1];
- break;
- default:
- arc1 = arc0 = 0;
- if(little_endian()) { /* Little endian (x86) */
- const unsigned char *ps, *pe;
- /* If more significant bytes are present,
- * make them > 255 quick */
- for(ps = (const unsigned char *)arcs + 1, pe = ps+arc_type_size;
- ps < pe; ps++)
- arc0 |= *ps, arc1 |= *(ps + arc_type_size);
- arc0 <<= CHAR_BIT, arc1 <<= CHAR_BIT;
- arc0 = *((const unsigned char *)arcs + 0);
- arc1 = *((const unsigned char *)arcs + arc_type_size);
- } else {
- const unsigned char *ps, *pe;
- /* If more significant bytes are present,
- * make them > 255 quick */
- for(ps = (const unsigned char *)arcs, pe = ps+arc_type_size - 1; ps < pe; ps++)
- arc0 |= *ps, arc1 |= *(ps + arc_type_size);
- arc0 = *((const unsigned char *)arcs + arc_type_size - 1);
- arc1 = *((const unsigned char *)arcs +(arc_type_size<< 1)-1);
- }
- }
+ arc0 = arcs[0];
+ arc1 = arcs[1];
- /*
- * The previous chapter left us with the first and the second arcs.
- * The values are not precise (that is, they are valid only if
- * they're less than 255), but OK for the purposes of making
- * the sanity test below.
- */
if(arc0 <= 1) {
- if(arc1 >= 39) {
+ if(arc1 >= 40) {
/* 8.19.4: At most 39 subsequent values (including 0) */
errno = ERANGE;
return -1;
}
- } else if(arc0 > 2) {
- /* 8.19.4: Only three values are allocated from the root node */
- errno = ERANGE;
- return -1;
- }
- /*
+ } else if(arc0 == 2) {
+ if(arc1 > ASN_OID_ARC_MAX - 80) {
+ errno = ERANGE;
+ return -1;
+ }
+ } else if(arc0 > 2) {
+ /* 8.19.4: Only three values are allocated from the root node */
+ errno = ERANGE;
+ return -1;
+ }
+
+ /*
* After above tests it is known that the value of arc0 is completely
* trustworthy (0..2). However, the arc1's value is still meaningless.
*/
- /*
- * Roughly estimate the maximum size necessary to encode these arcs.
- * This estimation implicitly takes in account the following facts,
- * that cancel each other:
- * * the first two arcs are encoded in a single value.
- * * the first value may require more space (+1 byte)
- * * the value of the first arc which is in range (0..2)
- */
- size = ((arc_type_size * CHAR_BIT + 6) / 7) * arc_slots;
- bp = buf = (uint8_t *)MALLOC(size + 1);
- if(!buf) {
- /* ENOMEM */
- return -1;
- }
+ /*
+ * Roughly estimate the maximum size necessary to encode these arcs.
+ * This estimation implicitly takes in account the following facts,
+ * that cancel each other:
+ * * the first two arcs are encoded in a single value.
+ * * the first value may require more space (+1 byte)
+ * * the value of the first arc which is in range (0..2)
+ */
+ size = ((sizeof(asn_oid_arc_t) * CHAR_BIT + 6) / 7) * arc_slots;
+ bp = buf = (uint8_t *)MALLOC(size + 1);
+ if(!buf) {
+ /* ENOMEM */
+ return -1;
+ }
- /*
- * Encode the first two arcs.
- * These require special treatment.
- */
- {
- uint8_t *tp;
- uint8_t first_value[1 + 16]; /* of two arcs */
- uint8_t *fv = first_value;
+ wrote = OBJECT_IDENTIFIER_set_single_arc(bp, size, arc0 * 40 + arc1);
+ if(wrote <= 0) {
+ FREEMEM(buf);
+ return -1;
+ }
+ assert(wrote <= size);
+ bp += wrote;
+ size -= wrote;
- /*
- * Simulate first_value = arc0 * 40 + arc1;
- */
- /* Copy the second (1'st) arcs[1] into the first_value */
- *fv++ = 0;
- arcs = ((const char *)arcs) + arc_type_size;
- if(little_endian()) {
- const uint8_t *aend = (const unsigned char *)arcs - 1;
- const uint8_t *a1 = (const unsigned char *)arcs + arc_type_size - 1;
- for(; a1 > aend; fv++, a1--) *fv = *a1;
- } else {
- const uint8_t *a1 = (const uint8_t *)arcs;
- const uint8_t *aend = a1 + arc_type_size;
- for(; a1 < aend; fv++, a1++) *fv = *a1;
- }
- /* Increase the first_value by arc0 */
- arc0 *= 40; /* (0..80) */
- for(tp = first_value + arc_type_size; tp >= first_value; tp--) {
- unsigned int v = *tp;
- v += arc0;
- *tp = v;
- if(v >= (1 << CHAR_BIT)) arc0 = v >> CHAR_BIT;
- else break;
- }
+ for(i = 2; i < arc_slots; i++) {
+ wrote = OBJECT_IDENTIFIER_set_single_arc(bp, size, arcs[i]);
+ if(wrote <= 0) {
+ FREEMEM(buf);
+ return -1;
+ }
+ assert(wrote <= size);
+ bp += wrote;
+ size -= wrote;
+ assert(wrote <= size);
+ }
- assert(tp >= first_value);
+ assert(size >= 0);
- bp += OBJECT_IDENTIFIER_set_single_arc(bp, first_value,
- fv - first_value, 1);
- }
-
- /*
- * Save the rest of arcs.
- */
- for(arcs = ((const char *)arcs) + arc_type_size, i = 2;
- i < arc_slots;
- i++, arcs = ((const char *)arcs) + arc_type_size) {
- bp += OBJECT_IDENTIFIER_set_single_arc(bp,
- arcs, arc_type_size, 0);
- }
-
- assert((unsigned)(bp - buf) <= size);
-
- /*
+ /*
* Replace buffer.
*/
- oid->size = bp - buf;
- bp = oid->buf;
- oid->buf = buf;
+ st->size = bp - buf;
+ bp = st->buf;
+ st->buf = buf;
+ st->buf[st->size] = '\0';
if(bp) FREEMEM(bp);
return 0;
}
-
-int
+ssize_t
OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
- long *arcs, unsigned int arcs_slots, const char **opt_oid_text_end) {
- unsigned int arcs_count = 0;
- const char *oid_end;
+ asn_oid_arc_t *arcs, size_t arcs_count,
+ const char **opt_oid_text_end) {
+ size_t num_arcs = 0;
+ const char *oid_end;
enum {
ST_LEADSPACE,
ST_TAILSPACE,
@@ -673,7 +469,7 @@
ST_WAITDIGITS /* Next character is expected to be a digit */
} state = ST_LEADSPACE;
- if(!oid_text || oid_txt_length < -1 || (arcs_slots && !arcs)) {
+ if(!oid_text || oid_txt_length < -1 || (arcs_count && !arcs)) {
if(opt_oid_text_end) *opt_oid_text_end = oid_text;
errno = EINVAL;
return -1;
@@ -682,32 +478,33 @@
if(oid_txt_length == -1)
oid_txt_length = strlen(oid_text);
-#define _OID_CAPTURE_ARC(oid_text, oid_end) do { \
- const char *endp = oid_end; \
- long value; \
- switch(asn_strtol_lim(oid_text, &endp, &value)) { \
- case ASN_STRTOX_EXTRA_DATA: \
- case ASN_STRTOX_OK: \
- if(arcs_count < arcs_slots) \
- arcs[arcs_count] = value; \
- arcs_count++; \
- oid_text = endp - 1; \
- break; \
- case ASN_STRTOX_ERROR_RANGE: \
- if(opt_oid_text_end) \
- *opt_oid_text_end = oid_text; \
- errno = ERANGE; \
- return -1; \
- case ASN_STRTOX_ERROR_INVAL: \
- case ASN_STRTOX_EXPECT_MORE: \
- if(opt_oid_text_end) \
- *opt_oid_text_end = oid_text; \
- errno = EINVAL; \
- return -1; \
- } \
- } while(0)
+#define _OID_CAPTURE_ARC(oid_text, oid_end) \
+ do { \
+ const char *endp = oid_end; \
+ unsigned long value; \
+ switch(asn_strtoul_lim(oid_text, &endp, &value)) { \
+ case ASN_STRTOX_EXTRA_DATA: \
+ case ASN_STRTOX_OK: \
+ if(value <= ASN_OID_ARC_MAX) { \
+ if(num_arcs < arcs_count) arcs[num_arcs] = value; \
+ num_arcs++; \
+ oid_text = endp - 1; \
+ break; \
+ } \
+ /* Fall through */ \
+ case ASN_STRTOX_ERROR_RANGE: \
+ if(opt_oid_text_end) *opt_oid_text_end = oid_text; \
+ errno = ERANGE; \
+ return -1; \
+ case ASN_STRTOX_ERROR_INVAL: \
+ case ASN_STRTOX_EXPECT_MORE: \
+ if(opt_oid_text_end) *opt_oid_text_end = oid_text; \
+ errno = EINVAL; \
+ return -1; \
+ } \
+ } while(0)
- for(oid_end = oid_text + oid_txt_length; oid_text<oid_end; oid_text++) {
+ for(oid_end = oid_text + oid_txt_length; oid_text<oid_end; oid_text++) {
switch(*oid_text) {
case 0x09: case 0x0a: case 0x0d: case 0x20: /* whitespace */
switch(state) {
@@ -772,7 +569,7 @@
return -1;
case ST_AFTERVALUE:
case ST_TAILSPACE:
- return arcs_count;
+ return num_arcs;
}
errno = EINVAL; /* Broken OID */
@@ -783,9 +580,9 @@
* Generate values from the list of interesting values, or just a random
* value up to the upper limit.
*/
-static uint32_t
-OBJECT_IDENTIFIER__biased_random_arc(uint32_t upper_bound) {
- static const uint16_t values[] = {0, 1, 127, 128, 129, 254, 255, 256};
+static asn_oid_arc_t
+OBJECT_IDENTIFIER__biased_random_arc(asn_oid_arc_t upper_bound) {
+ const asn_oid_arc_t values[] = {0, 1, 127, 128, 129, 254, 255, 256};
size_t idx;
switch(asn_random_between(0, 2)) {
@@ -811,7 +608,7 @@
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
OBJECT_IDENTIFIER_t *st;
- uint32_t arcs[5];
+ asn_oid_arc_t arcs[5];
size_t arcs_len = asn_random_between(2, 5);
size_t i;
@@ -826,13 +623,13 @@
}
arcs[0] = asn_random_between(0, 2);
- arcs[1] =
- OBJECT_IDENTIFIER__biased_random_arc(arcs[0] <= 1 ? 39 : UINT_MAX);
+ arcs[1] = OBJECT_IDENTIFIER__biased_random_arc(
+ arcs[0] <= 1 ? 39 : (ASN_OID_ARC_MAX - 80));
for(i = 2; i < arcs_len; i++) {
- arcs[i] = OBJECT_IDENTIFIER__biased_random_arc(UINT_MAX);
+ arcs[i] = OBJECT_IDENTIFIER__biased_random_arc(ASN_OID_ARC_MAX);
}
- if(OBJECT_IDENTIFIER_set_arcs(st, arcs, sizeof(arcs[0]), arcs_len)) {
+ if(OBJECT_IDENTIFIER_set_arcs(st, arcs, arcs_len)) {
if(st != *sptr) {
ASN_STRUCT_FREE(*td, st);
}
@@ -841,5 +638,6 @@
*sptr = st;
+ result_ok.length = st->size;
return result_ok;
}
diff --git a/skeletons/OBJECT_IDENTIFIER.h b/skeletons/OBJECT_IDENTIFIER.h
index d160e43..7336285 100644
--- a/skeletons/OBJECT_IDENTIFIER.h
+++ b/skeletons/OBJECT_IDENTIFIER.h
@@ -14,6 +14,9 @@
extern "C" {
#endif
+typedef uint32_t asn_oid_arc_t;
+#define ASN_OID_ARC_MAX (~((asn_oid_arc_t)0))
+
typedef ASN__PRIMITIVE_TYPE_t OBJECT_IDENTIFIER_t;
extern asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER;
@@ -40,50 +43,45 @@
**********************************/
/*
- * This function fills an (_arcs) array with OBJECT IDENTIFIER arcs
- * up to specified (_arc_slots) elements.
- *
+ * This function fills an (arcs) array with OBJECT IDENTIFIER arcs
+ * up to specified (arc_slots) elements.
+ *
* EXAMPLE:
* void print_arcs(OBJECT_IDENTIFIER_t *oid) {
- * unsigned long fixed_arcs[10]; // Try with fixed space first
- * unsigned long *arcs = fixed_arcs;
- * int arc_type_size = sizeof(fixed_arcs[0]); // sizeof(long)
- * int arc_slots = sizeof(fixed_arcs)/sizeof(fixed_arcs[0]); // 10
- * int count; // Real number of arcs.
+ * asn_oid_arc_t fixed_arcs[10]; // Try with fixed space first
+ * asn_oid_arc_t *arcs = fixed_arcs;
+ * size_t arc_slots = sizeof(fixed_arcs)/sizeof(fixed_arcs[0]); // 10
+ * ssize_t count; // Real number of arcs.
* int i;
- *
- * count = OBJECT_IDENTIFIER_get_arcs(oid, arcs,
- * arc_type_size, arc_slots);
+ *
+ * count = OBJECT_IDENTIFIER_get_arcs(oid, arcs, arc_slots);
* // If necessary, reallocate arcs array and try again.
* if(count > arc_slots) {
* arc_slots = count;
- * arcs = malloc(arc_type_size * arc_slots);
+ * arcs = malloc(sizeof(asn_oid_arc_t) * arc_slots);
* if(!arcs) return;
- * count = OBJECT_IDENTIFIER_get_arcs(oid, arcs,
- * arc_type_size, arc_slots);
+ * count = OBJECT_IDENTIFIER_get_arcs(oid, arcs, arc_slots);
* assert(count == arc_slots);
* }
- *
+ *
* // Print the contents of the arcs array.
* for(i = 0; i < count; i++)
- * printf("%d\n", arcs[i]);
- *
+ * printf("%"PRIu32"\n", arcs[i]);
+ *
* // Avoid memory leak.
* if(arcs != fixed_arcs) free(arcs);
* }
- *
+ *
* RETURN VALUES:
* -1/EINVAL: Invalid arguments (oid is missing)
* -1/ERANGE: One or more arcs have value out of array cell type range.
* >=0: Number of arcs contained in the OBJECT IDENTIFIER
- *
- * WARNING: The function always returns the real number of arcs,
- * even if there is no sufficient (_arc_slots) provided.
+ *
+ * WARNING: The function always returns the actual number of arcs,
+ * even if there is no sufficient (arc_slots) provided.
*/
-int OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *_oid,
- void *_arcs, /* e.g., unsigned int arcs[N] */
- unsigned int _arc_type_size, /* e.g., sizeof(arcs[0]) */
- unsigned int _arc_slots /* e.g., N */);
+ssize_t OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *oid,
+ asn_oid_arc_t *arcs, size_t arc_slots);
/*
* This functions initializes the OBJECT IDENTIFIER object with
@@ -95,25 +93,13 @@
* -1/ENOMEM: Memory allocation failed
* 0: The object was initialized with new arcs.
*/
-int OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *_oid,
- const void *_arcs, /* e.g., unsigned int arcs[N] */
- unsigned int _arc_type_size, /* e.g., sizeof(arcs[0]) */
- unsigned int _arc_slots /* e.g., N */);
+int OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *oid,
+ const asn_oid_arc_t *arcs, size_t arcs_count);
-/*
- * Print the specified OBJECT IDENTIFIER arc.
- */
-int OBJECT_IDENTIFIER_print_arc(const uint8_t *arcbuf, int arclen,
- int add, /* Arbitrary offset, required to process the first two arcs */
- asn_app_consume_bytes_f *cb, void *app_key);
-
-/* Same as above, but returns the number of written digits, instead of 0 */
-ssize_t OBJECT_IDENTIFIER__dump_arc(const uint8_t *arcbuf, int arclen, int add,
- asn_app_consume_bytes_f *cb, void *app_key);
/*
* Parse the OBJECT IDENTIFIER textual representation ("1.3.6.1.4.1.9363").
- * No arc can exceed the (0..signed_long_max) range (typically, 0..2G if L32).
+ * No arc can exceed the (0..ASN_OID_ARC_MAX, which is the same as UINT32_MAX).
* This function is not specific to OBJECT IDENTIFIER, it may be used to parse
* the RELATIVE-OID data, or any other data consisting of dot-separated
* series of numeric values.
@@ -129,20 +115,38 @@
* >= 0: Number of arcs contained in the OBJECT IDENTIFIER.
*
* WARNING: The function always returns the real number of arcs,
- * even if there is no sufficient (_arc_slots) provided.
- * This is useful for (_arc_slots) value estimation.
+ * even if there is no sufficient (arc_slots) provided.
+ * This is useful for (arc_slots) value estimation.
*/
-int OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
- long arcs[], unsigned int arcs_slots, const char **opt_oid_text_end);
+ssize_t OBJECT_IDENTIFIER_parse_arcs(const char *oid_text,
+ ssize_t oid_txt_length,
+ asn_oid_arc_t *arcs, size_t arcs_count,
+ const char **opt_oid_text_end);
/*
* Internal functions.
* Used by RELATIVE-OID implementation in particular.
*/
-int OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, unsigned int arclen,
- signed int add, void *value, unsigned int value_size);
-int OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf,
- const void *arcval, unsigned int arcval_size, int _prepared_order);
+
+/*
+ * Retrieve a single arc of size from the (arcbuf) buffer.
+ * RETURN VALUES:
+ * -1: Failed to retrieve the value from the (arcbuf).
+ * >0: Number of bytes consumed from the (arcbuf), <= (arcbuf_len).
+ */
+ssize_t OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf,
+ size_t arcbuf_len,
+ asn_oid_arc_t *ret_value);
+
+/*
+ * Write the unterminated arc value into the (arcbuf) which has the size at
+ * least (arcbuf_len).
+ * RETURN VALUES:
+ * -1: (arcbuf_len) size is not sufficient to write the value.
+ * <n>: Number of bytes appended to the arcbuf (<= arcbuf_len).
+ */
+ssize_t OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, size_t arcbuf_len,
+ asn_oid_arc_t arc_value);
#ifdef __cplusplus
}
diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c
index 33bfd4a..3eb2276 100644
--- a/skeletons/RELATIVE-OID.c
+++ b/skeletons/RELATIVE-OID.c
@@ -58,31 +58,38 @@
static ssize_t
RELATIVE_OID__dump_body(const RELATIVE_OID_t *st, asn_app_consume_bytes_f *cb, void *app_key) {
- ssize_t wrote = 0;
- ssize_t ret;
- size_t startn;
- size_t i;
+ char scratch[32];
+ size_t produced = 0;
+ size_t off = 0;
- for(i = 0, startn = 0; i < st->size; i++) {
- uint8_t b = st->buf[i];
- if((b & 0x80)) /* Continuation expected */
- continue;
- if(startn) {
- /* Separate arcs */
- if(cb(".", 1, app_key) < 0)
- return -1;
- wrote++;
- }
+ for(;;) {
+ asn_oid_arc_t arc;
+ ssize_t rd = OBJECT_IDENTIFIER_get_single_arc(st->buf + off,
+ st->size - off, &arc);
+ if(rd < 0) {
+ return -1;
+ } else if(rd == 0) {
+ /* No more arcs. */
+ break;
+ } else {
+ int ret = snprintf(scratch, sizeof(scratch), "%s%" PRIu32,
+ off ? "." : "", arc);
+ if(ret >= (ssize_t)sizeof(scratch)) {
+ return -1;
+ }
+ produced += ret;
+ off += rd;
+ assert(off <= st->size);
+ if(cb(scratch, ret, app_key) < 0) return -1;
+ }
+ }
- ret = OBJECT_IDENTIFIER__dump_arc(&st->buf[startn],
- i - startn + 1, 0, cb, app_key);
- if(ret < 0) return -1;
- wrote += ret;
+ if(off != st->size) {
+ ASN_DEBUG("Could not scan to the end of Object Identifier");
+ return -1;
+ }
- startn = i + 1;
- }
-
- return wrote;
+ return produced;
}
int
@@ -111,41 +118,41 @@
RELATIVE_OID_t *st = (RELATIVE_OID_t *)sptr;
const char *chunk_end = (const char *)chunk_buf + chunk_size;
const char *endptr;
- long s_arcs[6];
- long *arcs = s_arcs;
- int arcs_count;
+ asn_oid_arc_t s_arcs[6];
+ asn_oid_arc_t *arcs = s_arcs;
+ ssize_t num_arcs;
int ret;
(void)td;
- arcs_count = OBJECT_IDENTIFIER_parse_arcs(
- (const char *)chunk_buf, chunk_size,
- arcs, sizeof(s_arcs)/sizeof(s_arcs[0]), &endptr);
- if(arcs_count < 0) {
- /* Expecting at least one arc arcs */
- return XPBD_BROKEN_ENCODING;
- } else if(arcs_count == 0) {
- return XPBD_NOT_BODY_IGNORE;
- }
- assert(endptr == chunk_end);
+ num_arcs = OBJECT_IDENTIFIER_parse_arcs(
+ (const char *)chunk_buf, chunk_size, arcs,
+ sizeof(s_arcs) / sizeof(s_arcs[0]), &endptr);
+ if(num_arcs < 0) {
+ /* Expecting at least one arc arcs */
+ return XPBD_BROKEN_ENCODING;
+ } else if(num_arcs == 0) {
+ return XPBD_NOT_BODY_IGNORE;
+ }
+ assert(endptr == chunk_end);
- if((size_t)arcs_count > sizeof(s_arcs)/sizeof(s_arcs[0])) {
- arcs = (long *)MALLOC(arcs_count * sizeof(long));
- if(!arcs) return XPBD_SYSTEM_FAILURE;
- ret = OBJECT_IDENTIFIER_parse_arcs(
- (const char *)chunk_buf, chunk_size,
- arcs, arcs_count, &endptr);
- if(ret != arcs_count)
- return XPBD_SYSTEM_FAILURE; /* assert?.. */
- }
+ if((size_t)num_arcs > sizeof(s_arcs) / sizeof(s_arcs[0])) {
+ arcs = (asn_oid_arc_t *)MALLOC(num_arcs * sizeof(arcs[0]));
+ if(!arcs) return XPBD_SYSTEM_FAILURE;
+ ret = OBJECT_IDENTIFIER_parse_arcs((const char *)chunk_buf, chunk_size,
+ arcs, num_arcs, &endptr);
+ if(ret != num_arcs) {
+ return XPBD_SYSTEM_FAILURE; /* assert?.. */
+ }
+ }
- /*
- * Convert arcs into BER representation.
- */
- ret = RELATIVE_OID_set_arcs(st, arcs, sizeof(*arcs), arcs_count);
- if(arcs != s_arcs) FREEMEM(arcs);
+ /*
+ * Convert arcs into BER representation.
+ */
+ ret = RELATIVE_OID_set_arcs(st, arcs, num_arcs);
+ if(arcs != s_arcs) FREEMEM(arcs);
- return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED;
+ return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED;
}
asn_dec_rval_t
@@ -177,48 +184,51 @@
ASN__ENCODED_OK(er);
}
-int
-RELATIVE_OID_get_arcs(const RELATIVE_OID_t *roid,
- void *arcs, unsigned int arc_type_size, unsigned int arc_slots) {
- void *arcs_end = (char *)arcs + (arc_slots * arc_type_size);
- int num_arcs = 0;
- size_t startn = 0;
- size_t i;
+ssize_t
+RELATIVE_OID_get_arcs(const RELATIVE_OID_t *st, asn_oid_arc_t *arcs,
+ size_t arcs_count) {
+ size_t num_arcs = 0;
+ size_t off;
- if(!roid || !roid->buf) {
- errno = EINVAL;
- return -1;
- }
+ if(!st || !st->buf) {
+ errno = EINVAL;
+ return -1;
+ }
- for(i = 0; i < roid->size; i++) {
- uint8_t b = roid->buf[i];
- if((b & 0x80)) /* Continuation expected */
- continue;
+ for(off = 0;;) {
+ asn_oid_arc_t arc;
+ ssize_t rd = OBJECT_IDENTIFIER_get_single_arc(st->buf + off,
+ st->size - off, &arc);
+ if(rd < 0) {
+ return -1;
+ } else if(rd == 0) {
+ /* No more arcs. */
+ break;
+ } else {
+ off += rd;
+ if(num_arcs < arcs_count) {
+ arcs[num_arcs] = arc;
+ }
+ num_arcs++;
+ }
+ }
- if(arcs < arcs_end) {
- if(OBJECT_IDENTIFIER_get_single_arc(
- &roid->buf[startn],
- i - startn + 1, 0,
- arcs, arc_type_size))
- return -1;
- arcs = ((char *)arcs) + arc_type_size;
- num_arcs++;
- }
-
- startn = i + 1;
- }
+ if(off != st->size) {
+ return -1;
+ }
return num_arcs;
}
int
-RELATIVE_OID_set_arcs(RELATIVE_OID_t *roid, void *arcs, unsigned int arc_type_size, unsigned int arcs_slots) {
- uint8_t *buf;
+RELATIVE_OID_set_arcs(RELATIVE_OID_t *st, const asn_oid_arc_t *arcs,
+ size_t arcs_count) {
+ uint8_t *buf;
uint8_t *bp;
- unsigned int size;
- unsigned int i;
+ size_t size;
+ size_t i;
- if(roid == NULL || arcs == NULL || arc_type_size < 1) {
+ if(!st || !arcs) {
errno = EINVAL;
return -1;
}
@@ -226,8 +236,8 @@
/*
* Roughly estimate the maximum size necessary to encode these arcs.
*/
- size = ((arc_type_size * CHAR_BIT + 6) / 7) * arcs_slots;
- bp = buf = (uint8_t *)MALLOC(size + 1);
+ size = ((sizeof(asn_oid_arc_t) * CHAR_BIT + 6) / 7) * arcs_count;
+ bp = buf = (uint8_t *)MALLOC(size + 1);
if(!buf) {
/* ENOMEM */
return -1;
@@ -236,19 +246,26 @@
/*
* Encode the arcs.
*/
- for(i = 0; i < arcs_slots; i++, arcs = ((char *)arcs) + arc_type_size) {
- bp += OBJECT_IDENTIFIER_set_single_arc(bp,
- arcs, arc_type_size, 0);
- }
+ for(i = 0; i < arcs_count; i++) {
+ ssize_t wrote = OBJECT_IDENTIFIER_set_single_arc(bp, size, arcs[i]);
+ if(wrote <= 0) {
+ FREEMEM(buf);
+ return -1;
+ }
+ assert((size_t)wrote <= size);
+ bp += wrote;
+ size -= wrote;
+ }
- assert((unsigned)(bp - buf) <= size);
+ assert(size >= 0);
/*
* Replace buffer.
*/
- roid->size = (int)(bp - buf);
- bp = roid->buf;
- roid->buf = buf;
+ st->size = bp - buf;
+ bp = st->buf;
+ st->buf = buf;
+ st->buf[st->size] = '\0';
if(bp) FREEMEM(bp);
return 0;
@@ -258,7 +275,7 @@
/*
* Generate values from the list of interesting values, or just a random value.
*/
-static uint32_t
+static asn_oid_arc_t
RELATIVE_OID__biased_random_arc() {
static const uint16_t values[] = {0, 1, 127, 128, 129, 254, 255, 256};
@@ -276,15 +293,16 @@
asn_random_fill_result_t
RELATIVE_OID_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
- const asn_encoding_constraints_t *constraints,
- size_t max_length) {
+ const asn_encoding_constraints_t *constraints,
+ size_t max_length) {
asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
RELATIVE_OID_t *st;
const int min_arcs = 1; /* A minimum of 1 arc is required */
- size_t arcs_len = asn_random_between(min_arcs, 3);
- uint32_t arcs[3];
+ asn_oid_arc_t arcs[3];
+ size_t arcs_len =
+ asn_random_between(min_arcs, sizeof(arcs) / sizeof(arcs[0]));
size_t i;
(void)constraints;
@@ -301,7 +319,7 @@
arcs[i] = RELATIVE_OID__biased_random_arc();
}
- if(RELATIVE_OID_set_arcs(st, arcs, sizeof(arcs[0]), arcs_len)) {
+ if(RELATIVE_OID_set_arcs(st, arcs, arcs_len)) {
if(st != *sptr) {
ASN_STRUCT_FREE(*td, st);
}
@@ -310,5 +328,6 @@
*sptr = st;
+ result_ok.length = st->size;
return result_ok;
}
diff --git a/skeletons/RELATIVE-OID.h b/skeletons/RELATIVE-OID.h
index 1eaf559..edae83d 100644
--- a/skeletons/RELATIVE-OID.h
+++ b/skeletons/RELATIVE-OID.h
@@ -37,12 +37,12 @@
**********************************/
/* See OBJECT_IDENTIFIER_get_arcs() function in OBJECT_IDENTIFIER.h */
-int RELATIVE_OID_get_arcs(const RELATIVE_OID_t *_roid,
- void *arcs, unsigned int arc_type_size, unsigned int arc_slots);
+ssize_t RELATIVE_OID_get_arcs(const RELATIVE_OID_t *, asn_oid_arc_t *arcs,
+ size_t arcs_count);
/* See OBJECT_IDENTIFIER_set_arcs() function in OBJECT_IDENTIFIER.h */
-int RELATIVE_OID_set_arcs(RELATIVE_OID_t *_roid,
- void *arcs, unsigned int arc_type_size, unsigned int arcs_slots);
+int RELATIVE_OID_set_arcs(RELATIVE_OID_t *, const asn_oid_arc_t *arcs,
+ size_t arcs_count);
#ifdef __cplusplus
}
diff --git a/skeletons/asn_internal.h b/skeletons/asn_internal.h
index 09093b9..e308182 100644
--- a/skeletons/asn_internal.h
+++ b/skeletons/asn_internal.h
@@ -38,7 +38,7 @@
*/
#ifndef ASN_DEBUG /* If debugging code is not defined elsewhere... */
#if EMIT_ASN_DEBUG == 1 /* And it was asked to emit this code... */
-#ifdef __GNUC__
+#if __STDC_VERSION__ >= 199901L
#ifdef ASN_THREAD_SAFE
/* Thread safety requires sacrifice in output indentation:
* Retain empty definition of ASN_DEBUG_INDENT_ADD. */
@@ -55,10 +55,10 @@
fprintf(stderr, " (%s:%d)\n", \
__FILE__, __LINE__); \
} while(0)
-#else /* !__GNUC__ */
+#else /* !C99 */
void CC_PRINTFLIKE(1, 2) ASN_DEBUG_f(const char *fmt, ...);
#define ASN_DEBUG ASN_DEBUG_f
-#endif /* __GNUC__ */
+#endif /* C99 */
#else /* EMIT_ASN_DEBUG != 1 */
#if __STDC_VERSION__ >= 199901L
#define ASN_DEBUG(...) do{}while(0)
diff --git a/tests/tests-skeletons/check-OIDs.c b/tests/tests-skeletons/check-OIDs.c
index 951f752..fc87841 100644
--- a/tests/tests-skeletons/check-OIDs.c
+++ b/tests/tests-skeletons/check-OIDs.c
@@ -17,7 +17,7 @@
check_OID(int lineno, uint8_t *buf, size_t len, unsigned *ck_buf, int ck_len) {
OBJECT_IDENTIFIER_t *oid;
asn_dec_rval_t rval;
- unsigned long arcs[10];
+ uint32_t arcs[10];
int alen;
int i;
@@ -41,17 +41,17 @@
printf("\n");
memset(arcs, 'A', sizeof(arcs));
- alen = OBJECT_IDENTIFIER_get_arcs(oid,
- arcs, sizeof(arcs[0]), sizeof(arcs)/sizeof(arcs[0]));
- assert(alen > 0);
+ alen =
+ OBJECT_IDENTIFIER_get_arcs(oid, arcs, sizeof(arcs) / sizeof(arcs[0]));
+ assert(alen > 0);
printf("OBJECT_IDENTIFIER_get_arcs() => {");
/*
* Make sure they are equivalent.
*/
for(i = 0; i < alen; i++) {
- printf(" %lu", arcs[i]);
- if(alen == ck_len) {
+ printf(" %" PRIu32, arcs[i]);
+ if(alen == ck_len) {
assert(arcs[i] == ck_buf[i]);
}
}
@@ -62,15 +62,16 @@
}
static void
-check_ROID(int lineno, uint8_t *buf, size_t len, unsigned *ck_buf, int ck_len) {
- RELATIVE_OID_t *oid;
+check_ROID(int lineno, uint8_t *buf, size_t len, unsigned *ck_buf,
+ size_t ck_len) {
+ RELATIVE_OID_t *oid;
asn_dec_rval_t rval;
- unsigned long arcs[10];
+ uint32_t arcs[10];
int alen;
- int i;
+ size_t i;
printf("%03d: Checking {", lineno);
- for(i = 0; i < (ssize_t)len; i++) { printf("%s%02x", i?" ":"", buf[i]); }
+ for(i = 0; i < len; i++) { printf("%s%02x", i?" ":"", buf[i]); }
printf("} against {");
for(i = 0; i < ck_len; i++) { printf("%s%u", i?" ":"", ck_buf[i]); }
printf("}\n");
@@ -89,9 +90,8 @@
printf("\n");
memset(arcs, 'A', sizeof(arcs));
- alen = RELATIVE_OID_get_arcs(oid,
- arcs, sizeof(arcs[0]), sizeof(arcs)/sizeof(arcs[0]));
- assert(alen > 0);
+ alen = RELATIVE_OID_get_arcs(oid, arcs, sizeof(arcs) / sizeof(arcs[0]));
+ assert(alen > 0);
assert(alen == ck_len);
/*
@@ -99,8 +99,8 @@
*/
printf("RELATIVE_OID_get_arcs() => {");
for(i = 0; i < alen; i++) {
- printf(" %lu", arcs[i]);
- assert(arcs[i] == ck_buf[i]);
+ printf(" %" PRIu32, arcs[i]);
+ assert(arcs[i] == ck_buf[i]);
}
printf(" }\n");
ASN_STRUCT_FREE(asn_DEF_RELATIVE_OID, oid);
@@ -113,27 +113,25 @@
int cycles = 100000000;
double a, b, c;
struct timeval tv;
- unsigned long value;
+ uint32_t value;
int i;
- ret = OBJECT_IDENTIFIER_get_single_arc(buf, sizeof(buf), 0, &value, sizeof(value));
- assert(ret == 0);
+ ret = OBJECT_IDENTIFIER_get_single_arc(buf, sizeof(buf), &value);
+ assert(ret == 0);
assert(value == 0x7040c20d);
gettimeofday(&tv, 0);
a = tv.tv_sec + tv.tv_usec / 1000000.0;
for(i = 0; i < cycles; i++) {
- ret = OBJECT_IDENTIFIER_get_single_arc(buf, sizeof(buf), 0,
- &value, sizeof(value));
+ ret = OBJECT_IDENTIFIER_get_single_arc(buf, sizeof(buf), &value);
}
assert(ret == 0);
assert(value == 0x7040c20d);
gettimeofday(&tv, 0);
b = tv.tv_sec + tv.tv_usec / 1000000.0;
for(i = 0; i < cycles; i++) {
- ret = OBJECT_IDENTIFIER_get_single_arc(buf, sizeof(buf), 0,
- &value, sizeof(value));
- }
+ ret = OBJECT_IDENTIFIER_get_single_arc(buf, sizeof(buf), &value);
+ }
assert(ret == 0);
assert(value == 0x7040c20d);
gettimeofday(&tv, 0);
@@ -147,55 +145,66 @@
return 0;
}
-static void check_parse(const char *oid_txt, int retval) {
+#define CHECK_PARSE(a, b) check_parse(__LINE__, a, b)
+static void check_parse(int lineno, const char *oid_txt, int retval) {
int ret;
- long l[2];
+ uint32_t arcs[2];
const char *p = oid_txt - 13;
assert(p < oid_txt);
- ret = OBJECT_IDENTIFIER_parse_arcs(oid_txt, -1, l, 2, &p);
- printf("[%s] => %d == %d\n", oid_txt, ret, retval);
+ ret = OBJECT_IDENTIFIER_parse_arcs(oid_txt, -1, arcs, 2, &p);
+ printf("%03d: [%s] => %d == %d\n", lineno, oid_txt, ret, retval);
assert(ret == retval);
assert(p >= oid_txt);
}
-static void check_xer(int expect_arcs, char *xer) {
- asn_dec_rval_t rc;
- RELATIVE_OID_t *st = 0;
- long arcs[10];
- int ret;
- int i;
+static void
+check_xer(int lineno, asn_TYPE_descriptor_t *td, ssize_t expect_arcs, char *xer,
+ const asn_oid_arc_t *expected_arcs) {
+ asn_dec_rval_t rc;
+ void *st = 0;
+ uint32_t arcs[10];
+ ssize_t got_arcs;
+ ssize_t i;
- printf("[%s] => ", xer); fflush(stdout);
- rc = asn_DEF_RELATIVE_OID.op->xer_decoder(0,
- &asn_DEF_RELATIVE_OID, (void **)&st, "t",
- xer, strlen(xer));
- if(expect_arcs == -1) {
+ printf("%03d: [%s] => ", lineno, xer);
+ fflush(stdout);
+ rc = td->op->xer_decoder(0, td, (void **)&st, "t", xer, strlen(xer));
+ if(expect_arcs == -1) {
if(rc.code != RC_OK) {
printf("-1\n");
- ASN_STRUCT_FREE(asn_DEF_RELATIVE_OID, st);
+ ASN_STRUCT_FREE(*td, st);
return;
}
}
assert(rc.code == RC_OK);
- ret = RELATIVE_OID_get_arcs(st, arcs, sizeof(arcs[0]),
- sizeof(arcs)/sizeof(arcs[0]));
- assert(ret < 10);
+ if(td == &asn_DEF_OBJECT_IDENTIFIER) {
+ got_arcs = OBJECT_IDENTIFIER_get_arcs(st, arcs,
+ sizeof(arcs) / sizeof(arcs[0]));
+ } else if(td == &asn_DEF_RELATIVE_OID) {
+ got_arcs =
+ RELATIVE_OID_get_arcs(st, arcs, sizeof(arcs) / sizeof(arcs[0]));
+ } else {
+ assert(!"Unreachable");
+ }
+ assert(got_arcs < 10);
if(expect_arcs == -1) {
- assert(ret == -1);
- ASN_STRUCT_FREE(asn_DEF_RELATIVE_OID, st);
+ assert(got_arcs == -1);
+ ASN_STRUCT_FREE(*td, st);
return;
}
- for(i = 0; i < ret; i++) {
+ for(i = 0; i < got_arcs; i++) {
if(i) printf(".");
- printf("%ld", arcs[i]);
- if(arcs[i] != i + 1) printf(" != %d\n", i + 1);
- assert(arcs[i] == i + 1);
+ printf("%" PRIu32, arcs[i]);
+ if(arcs[i] != expected_arcs[i]) {
+ printf(" != %" PRIu32 "\n", expected_arcs[i]);
+ }
+ assert(arcs[i] == expected_arcs[i]);
}
- printf(": %d == %d\n", ret, expect_arcs);
- assert(ret == expect_arcs);
- ASN_STRUCT_FREE(asn_DEF_RELATIVE_OID, st);
+ printf(": %zd == %zd\n", got_arcs, expect_arcs);
+ assert(got_arcs == expect_arcs);
+ ASN_STRUCT_FREE(*td, st);
}
#define CHECK_OID(n) \
@@ -208,118 +217,176 @@
static void
check_binary_parsing() {
+ /* {0 0} */
+ uint8_t buf0[] = {
+ 0x06, /* OBJECT IDENTIFIER */
+ 0x01, /* Length */
+ 0x00
+ };
+ uint32_t buf0_check[] = { 0, 0 };
+
/* {joint-iso-itu-t 230 3} */
uint8_t buf1[] = {
0x06, /* OBJECT IDENTIFIER */
0x03, /* Length */
0x82, 0x36, 0x03
};
- unsigned buf1_check[] = { 2, 230, 3 };
-
- /* {8571 3 2} */
- uint8_t buf2[] = {
- 0x0D, /* RELATIVE-OID */
- 0x04, /* Length */
- 0xC2, 0x7B, 0x03, 0x02
- };
- unsigned buf2_check[] = { 8571, 3, 2 };
+ uint32_t buf1_check[] = { 2, 230, 3 };
/* {joint-iso-itu-t 42 } */
- uint8_t buf3[] = {
+ uint8_t buf2[] = {
0x06, /* OBJECT IDENTIFIER */
0x01, /* Length */
0x7A
};
- unsigned buf3_check[] = { 2, 42 };
+ uint32_t buf2_check[] = { 2, 42 };
/* {joint-iso-itu-t 25957 } */
- uint8_t buf4[] = {
+ uint8_t buf3[] = {
0x06, /* OBJECT IDENTIFIER */
0x03, /* Length */
0x81, 0x80 + 0x4B, 0x35
};
- unsigned buf4_check[] = { 2, 25957 };
+ uint32_t buf3_check[] = { 2, 25957 };
/* { jounsigned-iso-itu-t 2 1 1 } */
- uint8_t buf5[] = {
+ uint8_t buf4[] = {
0x06, /* OBJECT IDENTIFIER */
0x03, /* Length */
0x52, 0x01, 0x01
};
- unsigned buf5_check[] = { 2, 2, 1, 1 };
+ uint32_t buf4_check[] = { 2, 2, 1, 1 };
/* { jounsigned-iso-itu-t 2 1 0 1 } */
- uint8_t buf6[] = {
+ uint8_t buf5[] = {
0x06, /* OBJECT IDENTIFIER */
0x04, /* Length */
0x52, 0x01, 0x00, 0x01
};
- unsigned buf6_check[] = { 2, 2, 1, 0, 1 };
+ uint32_t buf5_check[] = { 2, 2, 1, 0, 1 };
+ /* {0 0} */
+ uint8_t buf10[] = {
+ 0x0D, /* RELATIVE-OID */
+ 0x01, /* Length */
+ 0x00
+ };
+ uint32_t buf10_check[] = { 0 };
+
+ /* {0 0} */
+ uint8_t buf11[] = {
+ 0x0D, /* RELATIVE-OID */
+ 0x02, /* Length */
+ 0x00, 0x00
+ };
+ uint32_t buf11_check[] = { 0, 0 };
+
+ /* {8571 3 2} */
+ uint8_t buf12[] = {
+ 0x0D, /* RELATIVE-OID */
+ 0x04, /* Length */
+ 0xC2, 0x7B, 0x03, 0x02
+ };
+ uint32_t buf12_check[] = { 8571, 3, 2 };
+
+ CHECK_OID(0);
CHECK_OID(1);
- CHECK_ROID(2);
+ CHECK_OID(2);
CHECK_OID(3);
CHECK_OID(4);
CHECK_OID(5);
- CHECK_OID(6);
+
+ CHECK_ROID(10);
+ CHECK_ROID(11);
+ CHECK_ROID(12);
}
static void
check_text_parsing() {
- check_parse("", 0);
- check_parse(" ", 0);
- check_parse(".", -1);
- check_parse(" .", -1);
- check_parse(".1", -1);
- check_parse("1.", -1);
- check_parse("1. ", -1);
- check_parse(".1. ", -1);
- check_parse(" .1. ", -1);
- check_parse(" 1", 1);
- check_parse(" 1.2", 2);
- check_parse(" 1.", -1);
- check_parse(" 1. ", -1);
- check_parse("1. ", -1);
- check_parse("1.2", 2);
- check_parse("1.2 ", 2);
- check_parse("1.2 ", 2);
- check_parse(" 1.2 ", 2);
- check_parse("1. 2", -1);
- check_parse("1 .2", -1);
- check_parse(" 1 .2", -1);
- check_parse(" 1 .2 ", -1);
- check_parse("1 .2 ", -1);
- check_parse("1.+1", -1);
- check_parse("10.30.234.234", 4);
- check_parse("10.30.234.234 ", 4);
- check_parse("10.30.234. 234 ", -1);
- check_parse("10.30.234.234.", -1);
- check_parse("1.2000000000.3", 3);
- check_parse("1.2147483647.3", 3);
- if(sizeof(long) == 4) {
- check_parse("1.2147483648.3", -1); /* overflow on ILP32 */
- check_parse("1.2147483649.3", -1); /* overflow on ILP32 */
- check_parse("1.3000000000.3", -1);
- check_parse("1.4000000000.3", -1);
- check_parse("1.5000000000.3", -1);
- check_parse("1.6000000000.3", -1);
- check_parse("1.9000000000.3", -1);
- } else if(sizeof(long) == 8) {
- check_parse("1.2147483648.3", 3);
- check_parse("1.9223372036854775807.3", 3);
- check_parse("1.9223372036854775808.3", -1);
- }
- check_parse("1.900a0000000.3", -1);
- check_parse("1.900a.3", -1);
+ CHECK_PARSE("", 0);
+ CHECK_PARSE(" ", 0);
+ CHECK_PARSE(".", -1);
+ CHECK_PARSE(" .", -1);
+ CHECK_PARSE(".1", -1);
+ CHECK_PARSE("1.", -1);
+ CHECK_PARSE("1. ", -1);
+ CHECK_PARSE(".1. ", -1);
+ CHECK_PARSE(" .1. ", -1);
+ CHECK_PARSE(" 1", 1);
+ CHECK_PARSE(" 1.2", 2);
+ CHECK_PARSE(" 1.", -1);
+ CHECK_PARSE(" 1. ", -1);
+ CHECK_PARSE("1. ", -1);
+ CHECK_PARSE("1.2", 2);
+ CHECK_PARSE("1.2 ", 2);
+ CHECK_PARSE("1.2 ", 2);
+ CHECK_PARSE(" 1.2 ", 2);
+ CHECK_PARSE("1. 2", -1);
+ CHECK_PARSE("1 .2", -1);
+ CHECK_PARSE(" 1 .2", -1);
+ CHECK_PARSE(" 1 .2 ", -1);
+ CHECK_PARSE("1 .2 ", -1);
+ CHECK_PARSE("1.+1", -1);
+ CHECK_PARSE("2.0", 2);
+ CHECK_PARSE("2.1", 2);
+ CHECK_PARSE("10.30.234.234", 4);
+ CHECK_PARSE("10.30.234.234 ", 4);
+ CHECK_PARSE("10.30.234. 234 ", -1);
+ CHECK_PARSE("10.30.234.234.", -1);
+ CHECK_PARSE("1.2000000000.3", 3);
+ CHECK_PARSE("1.2147483647.3", 3);
+ CHECK_PARSE("1.4294967295.3", 3);
+ CHECK_PARSE("1.4294967296.3", -1); /* overflow on ILP32 */
+ CHECK_PARSE("1.3000000000.3", 3);
+ CHECK_PARSE("1.4000000000.3", 3);
+ CHECK_PARSE("1.5000000000.3", -1);
+ CHECK_PARSE("1.6000000000.3", -1);
+ CHECK_PARSE("1.9000000000.3", -1);
+ CHECK_PARSE("1.900a0000000.3", -1);
+ CHECK_PARSE("1.900a.3", -1);
}
+#define CHECK_XER(a, b, c, data) check_xer(__LINE__, &asn_DEF_##a, b, c, data)
+
static void
check_xer_parsing() {
- check_xer(-1, "<t></t>");
- check_xer(2, "<t>1.2</t>");
- check_xer(3, "<t>1.2.3</t>");
- check_xer(3, "<t> 1.2.3 </t>");
- check_xer(-1, "<t>1.2.3 1</t>");
+ asn_oid_arc_t zero_zero[] = {0, 0};
+ asn_oid_arc_t zero_one[] = {0, 1};
+ asn_oid_arc_t one_zero[] = {1, 0};
+ asn_oid_arc_t one_one[] = {1, 1};
+ asn_oid_arc_t one_two[] = {1, 2};
+ asn_oid_arc_t two_one[] = {2, 1};
+ asn_oid_arc_t one_two_three[] = {1, 2,3};
+
+ CHECK_XER(RELATIVE_OID, -1, "<t></t>", 0);
+ CHECK_XER(RELATIVE_OID, -1, "<t>1.</t>", 0);
+ CHECK_XER(RELATIVE_OID, -1, "<t>2.1.</t>", 0);
+ CHECK_XER(RELATIVE_OID, 2, "<t>0.0</t>", zero_zero);
+ CHECK_XER(RELATIVE_OID, 2, "<t>0.1</t>", zero_one);
+ CHECK_XER(RELATIVE_OID, 2, "<t>1.0</t>", one_zero);
+ CHECK_XER(RELATIVE_OID, 2, "<t>1.2</t>", one_two);
+ CHECK_XER(RELATIVE_OID, -1, "<t>1.-2</t>", 0);
+ CHECK_XER(RELATIVE_OID, -1, "<t>1.+2</t>", 0);
+ CHECK_XER(RELATIVE_OID, 3, "<t>1.2.3</t>", one_two_three);
+ CHECK_XER(RELATIVE_OID, 3, "<t> 1.2.3 </t>", one_two_three);
+ CHECK_XER(RELATIVE_OID, -1, "<t>1.2.3 1</t>", 0);
+ CHECK_XER(RELATIVE_OID, 2, "<t>2.1</t>", two_one);
+
+ CHECK_XER(OBJECT_IDENTIFIER, -1, "<t></t>", 0);
+ CHECK_XER(OBJECT_IDENTIFIER, -1, "<t>1</t>", 0);
+ CHECK_XER(OBJECT_IDENTIFIER, -1, "<t>1.</t>", 0);
+ CHECK_XER(OBJECT_IDENTIFIER, -1, "<t>2.1.</t>", 0);
+ CHECK_XER(OBJECT_IDENTIFIER, 2, "<t>0.0</t>", zero_zero);
+ CHECK_XER(OBJECT_IDENTIFIER, 2, "<t>0.1</t>", zero_one);
+ CHECK_XER(OBJECT_IDENTIFIER, 2, "<t>1.0</t>", one_zero);
+ CHECK_XER(OBJECT_IDENTIFIER, 2, "<t>1.1</t>", one_one);
+ CHECK_XER(OBJECT_IDENTIFIER, 2, "<t>1.2</t>", one_two);
+ CHECK_XER(OBJECT_IDENTIFIER, -1, "<t>1.-2</t>", 0);
+ CHECK_XER(OBJECT_IDENTIFIER, -1, "<t>1.+2</t>", 0);
+ CHECK_XER(OBJECT_IDENTIFIER, 3, "<t>1.2.3</t>", one_two_three);
+ CHECK_XER(OBJECT_IDENTIFIER, 3, "<t> 1.2.3 </t>", one_two_three);
+ CHECK_XER(OBJECT_IDENTIFIER, -1, "<t>1.2.3 1</t>", 0);
+ CHECK_XER(OBJECT_IDENTIFIER, 2, "<t> 2.1 </t>", two_one);
}
int