Commit a5b0288c authored by Lev Walkin's avatar Lev Walkin

encode BIT STRING in a minimum number of bits for CANONICAL-UPER

parent d17cf888
This diff is collapsed.
...@@ -30,14 +30,14 @@ asn_constr_check_f BIT_STRING_constraint; ...@@ -30,14 +30,14 @@ asn_constr_check_f BIT_STRING_constraint;
xer_type_encoder_f BIT_STRING_encode_xer; xer_type_encoder_f BIT_STRING_encode_xer;
oer_type_decoder_f BIT_STRING_decode_oer; oer_type_decoder_f BIT_STRING_decode_oer;
oer_type_encoder_f BIT_STRING_encode_oer; oer_type_encoder_f BIT_STRING_encode_oer;
per_type_decoder_f BIT_STRING_decode_uper;
per_type_encoder_f BIT_STRING_encode_uper;
asn_random_fill_f BIT_STRING_random_fill; asn_random_fill_f BIT_STRING_random_fill;
#define BIT_STRING_free OCTET_STRING_free #define BIT_STRING_free OCTET_STRING_free
#define BIT_STRING_decode_ber OCTET_STRING_decode_ber #define BIT_STRING_decode_ber OCTET_STRING_decode_ber
#define BIT_STRING_encode_der OCTET_STRING_encode_der #define BIT_STRING_encode_der OCTET_STRING_encode_der
#define BIT_STRING_decode_xer OCTET_STRING_decode_xer_binary #define BIT_STRING_decode_xer OCTET_STRING_decode_xer_binary
#define BIT_STRING_decode_uper OCTET_STRING_decode_uper
#define BIT_STRING_encode_uper OCTET_STRING_encode_uper
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -47,6 +47,8 @@ BIT_STRING_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_ ...@@ -47,6 +47,8 @@ BIT_STRING_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_
} }
if(expected_length < 1) { if(expected_length < 1) {
ASN__DECODE_FAILED;
} else if(expected_length > size) {
ASN__DECODE_STARVED; ASN__DECODE_STARVED;
} }
......
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>. * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
* All rights reserved. * All rights reserved.
* Redistribution and modifications are permitted subject to BSD license. * Redistribution and modifications are permitted subject to BSD license.
*/ */
...@@ -1356,11 +1356,10 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1356,11 +1356,10 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
const asn_per_constraint_t *cval; const asn_per_constraint_t *cval;
const asn_per_constraint_t *csiz; const asn_per_constraint_t *csiz;
asn_dec_rval_t rval = { RC_OK, 0 }; asn_dec_rval_t rval = { RC_OK, 0 };
BIT_STRING_t *st = (BIT_STRING_t *)*sptr; OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr;
ssize_t consumed_myself = 0; ssize_t consumed_myself = 0;
int repeat; int repeat;
enum { enum {
OS__BPC_BIT = 0,
OS__BPC_CHAR = 1, OS__BPC_CHAR = 1,
OS__BPC_U16 = 2, OS__BPC_U16 = 2,
OS__BPC_U32 = 4 OS__BPC_U32 = 4
...@@ -1381,11 +1380,9 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1381,11 +1380,9 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
switch(specs->subvariant) { switch(specs->subvariant) {
default: default:
case ASN_OSUBV_ANY: case ASN_OSUBV_ANY:
case ASN_OSUBV_BIT:
ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant); ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant);
RETURN(RC_FAIL); RETURN(RC_FAIL);
case ASN_OSUBV_BIT:
canonical_unit_bits = unit_bits = 1;
bpc = OS__BPC_BIT;
break; break;
case ASN_OSUBV_STR: case ASN_OSUBV_STR:
canonical_unit_bits = unit_bits = 8; canonical_unit_bits = unit_bits = 8;
...@@ -1411,7 +1408,7 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1411,7 +1408,7 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
* Allocate the string. * Allocate the string.
*/ */
if(!st) { if(!st) {
st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size)); st = (OCTET_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
if(!st) RETURN(RC_FAIL); if(!st) RETURN(RC_FAIL);
} }
...@@ -1460,10 +1457,6 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1460,10 +1457,6 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
if(ret < 0) RETURN(RC_WMORE); if(ret < 0) RETURN(RC_WMORE);
consumed_myself += unit_bits * csiz->upper_bound; consumed_myself += unit_bits * csiz->upper_bound;
st->buf[st->size] = 0; st->buf[st->size] = 0;
if(bpc == 0) {
int ubs = (csiz->upper_bound & 0x7);
st->bits_unused = ubs ? 8 - ubs : 0;
}
RETURN(RC_OK); RETURN(RC_OK);
} }
...@@ -1471,7 +1464,6 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1471,7 +1464,6 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
do { do {
ssize_t raw_len; ssize_t raw_len;
ssize_t len_bytes; ssize_t len_bytes;
ssize_t len_bits;
void *p; void *p;
int ret; int ret;
...@@ -1483,29 +1475,15 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -1483,29 +1475,15 @@ OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)", ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
(long)csiz->effective_bits, (long)raw_len, (long)csiz->effective_bits, (long)raw_len,
repeat ? "repeat" : "once", td->name); repeat ? "repeat" : "once", td->name);
if(bpc) { len_bytes = raw_len * bpc;
len_bytes = raw_len * bpc;
len_bits = len_bytes * unit_bits;
} else {
len_bits = raw_len;
len_bytes = (len_bits + 7) >> 3;
if(len_bits & 0x7)
st->bits_unused = 8 - (len_bits & 0x7);
/* len_bits be multiple of 16K if repeat is set */
}
p = REALLOC(st->buf, st->size + len_bytes + 1); p = REALLOC(st->buf, st->size + len_bytes + 1);
if(!p) RETURN(RC_FAIL); if(!p) RETURN(RC_FAIL);
st->buf = (uint8_t *)p; st->buf = (uint8_t *)p;
if(bpc) { ret = OCTET_STRING_per_get_characters(pd, &st->buf[st->size], raw_len,
ret = OCTET_STRING_per_get_characters(pd, bpc, unit_bits, cval->lower_bound,
&st->buf[st->size], raw_len, bpc, unit_bits, cval->upper_bound, pc);
cval->lower_bound, cval->upper_bound, pc); if(ret > 0) RETURN(RC_FAIL);
if(ret > 0) RETURN(RC_FAIL);
} else {
ret = per_get_many_bits(pd, &st->buf[st->size],
0, len_bits);
}
if(ret < 0) RETURN(RC_WMORE); if(ret < 0) RETURN(RC_WMORE);
st->size += len_bytes; st->size += len_bytes;
} while(repeat); } while(repeat);
...@@ -1525,7 +1503,7 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, ...@@ -1525,7 +1503,7 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
: td->encoding_constraints.per_constraints; : td->encoding_constraints.per_constraints;
const asn_per_constraint_t *cval; const asn_per_constraint_t *cval;
const asn_per_constraint_t *csiz; const asn_per_constraint_t *csiz;
const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
asn_enc_rval_t er = { 0, 0, 0 }; asn_enc_rval_t er = { 0, 0, 0 };
int inext = 0; /* Lies not within extension root */ int inext = 0; /* Lies not within extension root */
unsigned int unit_bits; unsigned int unit_bits;
...@@ -1534,7 +1512,6 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, ...@@ -1534,7 +1512,6 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
const uint8_t *buf; const uint8_t *buf;
int ret; int ret;
enum { enum {
OS__BPC_BIT = 0,
OS__BPC_CHAR = 1, OS__BPC_CHAR = 1,
OS__BPC_U16 = 2, OS__BPC_U16 = 2,
OS__BPC_U32 = 4 OS__BPC_U32 = 4
...@@ -1556,14 +1533,8 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, ...@@ -1556,14 +1533,8 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
switch(specs->subvariant) { switch(specs->subvariant) {
default: default:
case ASN_OSUBV_ANY: case ASN_OSUBV_ANY:
ASN__ENCODE_FAILED;
case ASN_OSUBV_BIT: case ASN_OSUBV_BIT:
canonical_unit_bits = unit_bits = 1; ASN__ENCODE_FAILED;
bpc = OS__BPC_BIT;
size_in_units = st->size * 8 - (st->bits_unused & 0x07);
ASN_DEBUG("BIT STRING of %zu bytes, %d bits unused",
size_in_units, st->bits_unused);
break;
case ASN_OSUBV_STR: case ASN_OSUBV_STR:
canonical_unit_bits = unit_bits = 8; canonical_unit_bits = unit_bits = 8;
if(cval->flags & APC_CONSTRAINED) if(cval->flags & APC_CONSTRAINED)
...@@ -1630,14 +1601,9 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, ...@@ -1630,14 +1601,9 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
ret = per_put_few_bits(po, size_in_units - csiz->lower_bound, ret = per_put_few_bits(po, size_in_units - csiz->lower_bound,
csiz->effective_bits); csiz->effective_bits);
if(ret) ASN__ENCODE_FAILED; if(ret) ASN__ENCODE_FAILED;
if(bpc) { ret = OCTET_STRING_per_put_characters(po, st->buf, size_in_units, bpc,
ret = OCTET_STRING_per_put_characters( unit_bits, cval->lower_bound,
po, st->buf, size_in_units, bpc, unit_bits, cval->lower_bound, cval->upper_bound, pc);
cval->upper_bound, pc);
} else {
assert(unit_bits == 1);
ret = per_put_many_bits(po, st->buf, size_in_units);
}
if(ret) ASN__ENCODE_FAILED; if(ret) ASN__ENCODE_FAILED;
ASN__ENCODED_OK(er); ASN__ENCODED_OK(er);
} }
...@@ -1654,21 +1620,14 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td, ...@@ -1654,21 +1620,14 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
ssize_t maySave = uper_put_length(po, size_in_units); ssize_t maySave = uper_put_length(po, size_in_units);
if(maySave < 0) ASN__ENCODE_FAILED; if(maySave < 0) ASN__ENCODE_FAILED;
ASN_DEBUG("Encoding %ld of %ld", (long)maySave, (long)sizeinunits); ASN_DEBUG("Encoding %zd of %zu", maySave, size_in_units);
if(bpc) { ret = OCTET_STRING_per_put_characters(po, buf, maySave, bpc, unit_bits,
ret = OCTET_STRING_per_put_characters(po, buf, maySave, bpc, cval->lower_bound,
unit_bits, cval->lower_bound, cval->upper_bound, pc);
cval->upper_bound, pc);
} else {
ret = per_put_many_bits(po, buf, maySave);
}
if(ret) ASN__ENCODE_FAILED; if(ret) ASN__ENCODE_FAILED;
if(bpc) buf += maySave * bpc;
buf += maySave * bpc;
else
buf += maySave >> 3;
size_in_units -= maySave; size_in_units -= maySave;
assert(!(maySave & 0x07) || !size_in_units); assert(!(maySave & 0x07) || !size_in_units);
} }
...@@ -1848,10 +1807,11 @@ OCTET_STRING_new_fromBuf(const asn_TYPE_descriptor_t *td, const char *str, ...@@ -1848,10 +1807,11 @@ OCTET_STRING_new_fromBuf(const asn_TYPE_descriptor_t *td, const char *str,
int int
OCTET_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr, OCTET_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
const void *bptr) { const void *bptr) {
const asn_OCTET_STRING_specifics_t *specs = td->specifics;
const OCTET_STRING_t *a = aptr; const OCTET_STRING_t *a = aptr;
const OCTET_STRING_t *b = bptr; const OCTET_STRING_t *b = bptr;
(void)td; assert(!specs || specs->subvariant != ASN_OSUBV_BIT);
if(a && b) { if(a && b) {
size_t common_prefix_size = a->size <= b->size ? a->size : b->size; size_t common_prefix_size = a->size <= b->size ? a->size : b->size;
...@@ -1863,18 +1823,6 @@ OCTET_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr, ...@@ -1863,18 +1823,6 @@ OCTET_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
} else if(a->size > b->size) { } else if(a->size > b->size) {
return 1; return 1;
} else { } else {
asn_OCTET_STRING_specifics_t *specs = td->specifics;
if(specs && specs->subvariant == ASN_OSUBV_BIT) {
const BIT_STRING_t *ba = aptr;
const BIT_STRING_t *bb = bptr;
if(ba->bits_unused > bb->bits_unused) {
return -1;
} else if(ba->bits_unused < bb->bits_unused) {
return 1;
} else {
return 0;
}
}
return 0; return 0;
} }
} else { } else {
...@@ -1943,22 +1891,22 @@ OCTET_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr, ...@@ -1943,22 +1891,22 @@ OCTET_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
case ASN_OSUBV_BIT: case ASN_OSUBV_BIT:
/* Handled by BIT_STRING itself. */ /* Handled by BIT_STRING itself. */
return result_failed; return result_failed;
case ASN_OSUBV_STR: case ASN_OSUBV_STR:
unit_bytes = 1; unit_bytes = 1;
clb = 0; clb = 0;
cub = 255; cub = 255;
break; break;
case ASN_OSUBV_U16: case ASN_OSUBV_U16:
unit_bytes = 2; unit_bytes = 2;
clb = 0; clb = 0;
cub = 65535; cub = 65535;
break; break;
case ASN_OSUBV_U32: case ASN_OSUBV_U32:
unit_bytes = 4; unit_bytes = 4;
clb = 0; clb = 0;
cub = 0x10FFFF; cub = 0x10FFFF;
break; break;
} }
if(!constraints) constraints = &td->encoding_constraints; if(!constraints) constraints = &td->encoding_constraints;
if(constraints->per_constraints) { if(constraints->per_constraints) {
...@@ -1979,8 +1927,9 @@ OCTET_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr, ...@@ -1979,8 +1927,9 @@ OCTET_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
const asn_per_constraint_t *pc = const asn_per_constraint_t *pc =
&td->encoding_constraints.per_constraints->size; &td->encoding_constraints.per_constraints->size;
if(pc->flags & APC_CONSTRAINED) { if(pc->flags & APC_CONSTRAINED) {
long suggested_upper_bound = long suggested_upper_bound = pc->upper_bound < (ssize_t)max_length
pc->upper_bound < max_length ? pc->upper_bound : max_length; ? pc->upper_bound
: max_length;
if(max_length < (size_t)pc->lower_bound) { if(max_length < (size_t)pc->lower_bound) {
return result_skipped; return result_skipped;
} }
......
...@@ -62,8 +62,8 @@ overrun_encoder_cb(const void *data, size_t size, void *keyp) { ...@@ -62,8 +62,8 @@ overrun_encoder_cb(const void *data, size_t size, void *keyp) {
key->buffer_size = 0; key->buffer_size = 0;
} else { } else {
memcpy((char *)key->buffer + key->computed_size, data, size); memcpy((char *)key->buffer + key->computed_size, data, size);
key->computed_size += size;
} }
key->computed_size += size;
return 0; return 0;
} }
...@@ -130,6 +130,10 @@ asn_encode_to_buffer(const asn_codec_ctx_t *opt_codec_ctx, ...@@ -130,6 +130,10 @@ asn_encode_to_buffer(const asn_codec_ctx_t *opt_codec_ctx,
er = asn_encode_internal(opt_codec_ctx, syntax, td, sptr, er = asn_encode_internal(opt_codec_ctx, syntax, td, sptr,
overrun_encoder_cb, &buf_key); overrun_encoder_cb, &buf_key);
if(er.encoded >= 0 && (size_t)er.encoded != buf_key.computed_size) {
ASN_DEBUG("asn_encode returned %zd yet wrote %zu bytes",
er.encoded, buf_key.computed_size);
}
assert(er.encoded < 0 || (size_t)er.encoded == buf_key.computed_size); assert(er.encoded < 0 || (size_t)er.encoded == buf_key.computed_size);
return er; return er;
......
-- Test encoding/decoding/transcoding of everything concerning the BIT STRING.
T ::= BIT STRING { foo(0) }
T ::= BIT STRING { foo(0) } (SIZE(0..1))
T ::= BIT STRING { foo(0) } (SIZE(1))
T ::= BIT STRING { foo(0) } (SIZE(1..MAX))
T ::= BIT STRING { foo(0) } (SIZE(1..2))
T ::= BIT STRING { foo(0) } (SIZE(2))
T ::= BIT STRING { foo(0) } (SIZE(2,...))
T ::= BIT STRING { foo(0), bar(65535) }
T ::= BIT STRING { foo(0), bar(65535) } (SIZE(0..16))
T ::= BIT STRING { foo(0), bar(65535) } (SIZE(16))
T ::= BIT STRING { foo(0), bar(2147483647) }
T ::= BIT STRING { foo(0), bar(2147483647) } (SIZE(1..MAX))
T ::= BIT STRING { foo(2147483648), bar(0), baz(2147483647) }
T ::= BIT STRING { foo(2147483648), baz(2147483647) }
T ::= BIT STRING { foo(2147483648), baz(2147483647) } (SIZE(32))
T ::= BIT STRING { foo(2147483648), baz(2147483647) } (SIZE(31,...))
T ::= BIT STRING { foo(2147483648), baz(2147483647) } (SIZE(0..32))
T ::= BIT STRING { foo(2147483648), baz(2147483647) } (SIZE(0..31,...))
-- Test encoding/decoding/transcoding of a simple string type
T ::= VisibleString
T ::= VisibleString ("Value Constraint")
T ::= VisibleString (SIZE(0))
T ::= VisibleString (SIZE(0,...))
T ::= VisibleString (SIZE(1))
T ::= VisibleString (SIZE(1)) (FROM("A".."B"))
T ::= VisibleString (SIZE(1,..))
T ::= VisibleString (SIZE(2))
T ::= VisibleString (SIZE(2,...))
T ::= VisibleString (SIZE(1..2))
T ::= VisibleString (SIZE(1..2,...))
T ::= VisibleString (SIZE(4..6,...)) (FROM("A".."B"))
T ::= VisibleString (SIZE(1..MAX)) FROM("A".."B"))
T ::= VisibleString (SIZE(1..127))
T ::= VisibleString (SIZE(1..128))
T ::= VisibleString (SIZE(1..129))
T ::= VisibleString (SIZE(5) INTERSECTION FROM("A".."Z"))
T ::= VisibleString (SIZE(64000)) -- Length is not encoded, #11.9.3.3
T ::= VisibleString (SIZE(32000..32002))
T ::= VisibleString (SIZE(32000..32002)) (FROM("A".."B"))
T ::= VisibleString (SIZE(32000..32002,...)) (FROM("A".."B"))
T ::= VisibleString (SIZE(65530..65535))
T ::= VisibleString (SIZE(65530..65536))
T ::= VisibleString (SIZE(4..6) INTERSECTION (FROM("A".."B")))
T ::= VisibleString (SIZE(4..6,...) INTERSECTION (FROM("A".."B")))
...@@ -66,7 +66,7 @@ verify_asn_type() { ...@@ -66,7 +66,7 @@ verify_asn_type() {
echo "Testing [$asn] ${where}" echo "Testing [$asn] ${where}"
mkdir -p ${RNDTEMP} mkdir -p ${RNDTEMP}
if (cd ${RNDTEMP} && compile_and_test "$asn" "$@"); then if (set -e && cd ${RNDTEMP} && compile_and_test "$asn" "$@"); then
echo "OK [$asn] ${where}" echo "OK [$asn] ${where}"
tests_succeeded=$((tests_succeeded+1)) tests_succeeded=$((tests_succeeded+1))
else else
...@@ -134,7 +134,7 @@ compile_and_test() { ...@@ -134,7 +134,7 @@ compile_and_test() {
done done
fi fi
return 0; return 0
} }
asn_compile() { asn_compile() {
...@@ -150,8 +150,11 @@ asn_compile() { ...@@ -150,8 +150,11 @@ asn_compile() {
test ! -f Makefile.am # Protection from accidental clobbering test ! -f Makefile.am # Protection from accidental clobbering
echo "Test DEFINITIONS ::= BEGIN $asn" > test.asn1 echo "Test DEFINITIONS ::= BEGIN $asn" > test.asn1
echo "END" >> test.asn1 echo "END" >> test.asn1
${abs_top_builddir}/asn1c/asn1c -S ${abs_top_srcdir}/skeletons \ if ! ${abs_top_builddir}/asn1c/asn1c -S ${abs_top_srcdir}/skeletons \
-gen-OER -gen-PER test.asn1 -gen-OER -gen-PER test.asn1
then
return 1
fi
rm -f converter-example.c rm -f converter-example.c
ln -sf ../random-test-driver.c || cp ../random-test-driver.c . ln -sf ../random-test-driver.c || cp ../random-test-driver.c .
echo "CFLAGS+= -DASN1_TEXT='$short_asn'" > Makefile echo "CFLAGS+= -DASN1_TEXT='$short_asn'" > Makefile
......
...@@ -190,9 +190,6 @@ generate_random_data(enum asn_transfer_syntax syntax, const char *top_dirname, i ...@@ -190,9 +190,6 @@ generate_random_data(enum asn_transfer_syntax syntax, const char *top_dirname, i
static void static void
check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) { check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) {
char tmp_buffer[512];
char *buffer = tmp_buffer;
size_t buffer_size = sizeof(tmp_buffer);
struct encoding_map enc; struct encoding_map enc;
for(size_t i = 0; i < sizeof(encodings)/sizeof(encodings[0]); i++) { for(size_t i = 0; i < sizeof(encodings)/sizeof(encodings[0]); i++) {
...@@ -205,6 +202,9 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) { ...@@ -205,6 +202,9 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) {
} }
for(int i = 0; i < iterations; i++) { for(int i = 0; i < iterations; i++) {
char tmp_buffer[512];
char *buffer = tmp_buffer;
size_t buffer_size = sizeof(tmp_buffer);
T_t *structure = 0; T_t *structure = 0;
T_t *decoded_structure = 0; T_t *decoded_structure = 0;
...@@ -228,6 +228,8 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) { ...@@ -228,6 +228,8 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) {
exit(EX_SOFTWARE); exit(EX_SOFTWARE);
} }
if(er.encoded > buffer_size && buffer == tmp_buffer) { if(er.encoded > buffer_size && buffer == tmp_buffer) {
fprintf(stderr, "Reallocate output buffer %zu -> %zu\n",
buffer_size, er.encoded);
buffer = malloc(er.encoded + 1); buffer = malloc(er.encoded + 1);
assert(buffer); assert(buffer);
buffer[er.encoded] = '\0'; buffer[er.encoded] = '\0';
...@@ -236,7 +238,11 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) { ...@@ -236,7 +238,11 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) {
} }
break; break;
} }
assert(er.encoded <= buffer_size); if(er.encoded > buffer_size) {
fprintf(stderr, "Data %zd does not fit into buffer %zu\n",
er.encoded, buffer_size);
assert(er.encoded <= buffer_size);
}
asn_dec_rval_t rval = asn_dec_rval_t rval =
asn_decode(0, syntax, &asn_DEF_T, (void **)&decoded_structure, asn_decode(0, syntax, &asn_DEF_T, (void **)&decoded_structure,
...@@ -244,9 +250,9 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) { ...@@ -244,9 +250,9 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) {
if(rval.code == RC_OK) { if(rval.code == RC_OK) {
/* Everything's cool... or is it? Expecting a proper consumed */ /* Everything's cool... or is it? Expecting a proper consumed */
if(rval.consumed != er.encoded) { if(rval.consumed != er.encoded) {
fprintf(stderr, "Encoded into %zd, yet consumed %zu", fprintf(stderr, "Encoded into %zd, yet consumed %zu\n",
er.encoded, rval.consumed); er.encoded, rval.consumed);
fprintf(stderr, "Structure:\n"); fprintf(stderr, "Original random structure:\n");
asn_fprint(stderr, &asn_DEF_T, structure); asn_fprint(stderr, &asn_DEF_T, structure);
assert(rval.consumed == er.encoded); assert(rval.consumed == er.encoded);
exit(EX_SOFTWARE); exit(EX_SOFTWARE);
...@@ -256,7 +262,7 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) { ...@@ -256,7 +262,7 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) {
"Decoding %zu bytes of T yielded %s after byte %zu\n", "Decoding %zu bytes of T yielded %s after byte %zu\n",
er.encoded, rval.code == RC_FAIL ? "RC_FAIL" : "RC_WMORE", er.encoded, rval.code == RC_FAIL ? "RC_FAIL" : "RC_WMORE",
rval.consumed); rval.consumed);
fprintf(stderr, "Structure:\n"); fprintf(stderr, "Original random structure:\n");
asn_fprint(stderr, &asn_DEF_T, structure); asn_fprint(stderr, &asn_DEF_T, structure);
exit(EX_SOFTWARE); exit(EX_SOFTWARE);
} }
...@@ -278,8 +284,6 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) { ...@@ -278,8 +284,6 @@ check_random_roundtrip(enum asn_transfer_syntax syntax, int iterations) {
if(buffer != tmp_buffer) { if(buffer != tmp_buffer) {
free(buffer); free(buffer);
buffer = tmp_buffer;
buffer_size = sizeof(tmp_buffer);
} }
if(i < 5) { if(i < 5) {
......
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