Commit 52b88e1b authored by Lev Walkin's avatar Lev Walkin

uper and oer SET OF and SEQUENCE OF verified

parent e5f0d94a
......@@ -149,7 +149,7 @@ SEQUENCE_OF_encode_uper(const asn_TYPE_descriptor_t *td,
const asn_per_constraint_t *ct;
asn_enc_rval_t er;
const asn_TYPE_member_t *elm = td->elements;
int seq;
size_t encoded_edx;
if(!sptr) ASN__ENCODE_FAILED;
list = _A_CSEQUENCE_FROM_VOID(sptr);
......@@ -158,59 +158,96 @@ SEQUENCE_OF_encode_uper(const asn_TYPE_descriptor_t *td,
ASN_DEBUG("Encoding %s as SEQUENCE OF (%d)", td->name, list->count);
if(constraints) ct = &constraints->size;
else if(td->encoding_constraints.per_constraints)
ct = &td->encoding_constraints.per_constraints->size;
else ct = 0;
/* If extensible constraint, check if size is in root */
if(ct) {
int not_in_root = (list->count < ct->lower_bound
|| list->count > ct->upper_bound);
ASN_DEBUG("lb %ld ub %ld %s",
ct->lower_bound, ct->upper_bound,
ct->flags & APC_EXTENSIBLE ? "ext" : "fix");
if(ct->flags & APC_EXTENSIBLE) {
/* Declare whether size is in extension root */
if(per_put_few_bits(po, not_in_root, 1))
ASN__ENCODE_FAILED;
if(not_in_root) ct = 0;
} else if(not_in_root && ct->effective_bits >= 0)
ASN__ENCODE_FAILED;
}
if(constraints) ct = &constraints->size;
else if(td->encoding_constraints.per_constraints)
ct = &td->encoding_constraints.per_constraints->size;
else ct = 0;
/* If extensible constraint, check if size is in root */
if(ct) {
int not_in_root =
(list->count < ct->lower_bound || list->count > ct->upper_bound);
ASN_DEBUG("lb %ld ub %ld %s", ct->lower_bound, ct->upper_bound,
ct->flags & APC_EXTENSIBLE ? "ext" : "fix");
if(ct->flags & APC_EXTENSIBLE) {
/* Declare whether size is in extension root */
if(per_put_few_bits(po, not_in_root, 1)) ASN__ENCODE_FAILED;
if(not_in_root) ct = 0;
} else if(not_in_root && ct->effective_bits >= 0) {
ASN__ENCODE_FAILED;
}
if(ct && ct->effective_bits >= 0) {
/* X.691, #19.5: No length determinant */
if(per_put_few_bits(po, list->count - ct->lower_bound,
ct->effective_bits))
ASN__ENCODE_FAILED;
}
if(ct && ct->effective_bits >= 0) {
/* X.691, #19.5: No length determinant */
if(per_put_few_bits(po, list->count - ct->lower_bound,
ct->effective_bits))
ASN__ENCODE_FAILED;
}
}
for(seq = -1; seq < list->count;) {
ssize_t mayEncode;
if(seq < 0) seq = 0;
if(ct && ct->effective_bits >= 0) {
mayEncode = list->count;
} else {
mayEncode = uper_put_length(po, list->count - seq, 0);
if(mayEncode < 0) ASN__ENCODE_FAILED;
}
while(mayEncode--) {
void *memb_ptr = list->array[seq++];
if(!memb_ptr) ASN__ENCODE_FAILED;
er = elm->type->op->uper_encoder(elm->type,
elm->encoding_constraints.per_constraints, memb_ptr, po);
if(er.encoded == -1)
ASN__ENCODE_FAILED;
}
}
for(encoded_edx = 0; (ssize_t)encoded_edx < list->count;) {
ssize_t may_encode;
size_t edx;
int need_eom = 0;
if(ct && ct->effective_bits >= 0) {
may_encode = list->count;
} else {
may_encode =
uper_put_length(po, list->count - encoded_edx, &need_eom);
if(may_encode < 0) ASN__ENCODE_FAILED;
}
for(edx = encoded_edx; edx < encoded_edx + may_encode; edx++) {
void *memb_ptr = list->array[edx];
if(!memb_ptr) ASN__ENCODE_FAILED;
er = elm->type->op->uper_encoder(
elm->type, elm->encoding_constraints.per_constraints, memb_ptr,
po);
if(er.encoded == -1) ASN__ENCODE_FAILED;
}
if(need_eom && uper_put_length(po, 0, 0))
ASN__ENCODE_FAILED; /* End of Message length */
encoded_edx += may_encode;
}
ASN__ENCODED_OK(er);
}
#endif /* ASN_DISABLE_PER_SUPPORT */
int
SEQUENCE_OF_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
const void *bptr) {
const asn_anonymous_sequence_ *a = _A_CSEQUENCE_FROM_VOID(aptr);
const asn_anonymous_sequence_ *b = _A_CSEQUENCE_FROM_VOID(bptr);
ssize_t idx;
if(a && b) {
ssize_t common_length = (a->count < b->count ? a->count : b->count);
for(idx = 0; idx < common_length; idx++) {
int ret = td->elements->type->op->compare_struct(
td->elements->type, a->array[idx], b->array[idx]);
if(ret) return ret;
}
if(idx < b->count) /* more elements in b */
return -1; /* a is shorter, so put it first */
if(idx < a->count) return 1;
} else if(!a) {
return -1;
} else if(!b) {
return 1;
}
return 0;
}
asn_TYPE_operation_t asn_OP_SEQUENCE_OF = {
SEQUENCE_OF_free,
SEQUENCE_OF_print,
......
......@@ -16,9 +16,14 @@ extern "C" {
* A set specialized functions dealing with the SEQUENCE OF type.
* Generally implemented using SET OF.
*/
asn_struct_compare_f SEQUENCE_OF_compare;
der_type_encoder_f SEQUENCE_OF_encode_der;
xer_type_encoder_f SEQUENCE_OF_encode_xer;
per_type_encoder_f SEQUENCE_OF_encode_uper;
extern asn_TYPE_operation_t asn_OP_SEQUENCE_OF;
#define SEQUENCE_OF_free SET_OF_free
#define SEQUENCE_OF_print SET_OF_print
#define SEQUENCE_OF_compare SET_OF_compare
#define SEQUENCE_OF_constraint SET_OF_constraint
#define SEQUENCE_OF_decode_ber SET_OF_decode_ber
#define SEQUENCE_OF_decode_xer SET_OF_decode_xer
......@@ -26,10 +31,6 @@ extern "C" {
#define SEQUENCE_OF_decode_oer SET_OF_decode_oer
#define SEQUENCE_OF_encode_oer SET_OF_encode_oer
#define SEQUENCE_OF_random_fill SET_OF_random_fill
der_type_encoder_f SEQUENCE_OF_encode_der;
xer_type_encoder_f SEQUENCE_OF_encode_xer;
per_type_encoder_f SEQUENCE_OF_encode_uper;
extern asn_TYPE_operation_t asn_OP_SEQUENCE_OF;
#ifdef __cplusplus
}
......
This diff is collapsed.
......@@ -153,7 +153,6 @@ SET_OF_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
case -1:
RETURN(RC_FAIL);
default:
ASN_DEBUG("ptr[] = %02x, advancing %" ASN_PRI_SIZE ", length=%" ASN_PRI_SIZE "", *(const uint8_t *)ptr, len_size, length);
ADVANCE(len_size);
ctx->left = length;
}
......@@ -164,6 +163,8 @@ SET_OF_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
/* Decode components of the extension root */
asn_TYPE_member_t *elm = td->elements;
asn_anonymous_set_ *list = _A_SET_FROM_VOID(st);
const void *base_ptr = ptr;
ber_tlv_len_t base_ctx_left = ctx->left;
assert(td->elements_count == 1);
......@@ -181,6 +182,15 @@ SET_OF_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
RETURN(RC_FAIL);
} else {
ctx->ptr = 0;
/*
* This check is to avoid compression bomb with
* specs like SEQUENCE/SET OF NULL which don't
* consume data at all.
*/
if(rv.consumed == 0 && base_ptr == ptr
&& (base_ctx_left - ctx->left) > 200) {
ASN__DECODE_FAILED;
}
break;
}
case RC_WMORE:
......
......@@ -32,6 +32,7 @@ uper_get_length(asn_per_data_t *pd, int ebits, size_t lower_bound,
value = ((value & 0x3f) << 8) | per_get_few_bits(pd, 8);
return value; /* potential -1 from per_get_few_bits passes through. */
} else if(value < 0) {
ASN_DEBUG("END of stream reached for PER");
return -1;
}
value &= 0x3f; /* this is "m" from X.691, #11.9.3.8 */
......
......@@ -42,6 +42,7 @@ TESTS += bundles/14-GeneralizedTime-bundle.txt
TESTS += bundles/15-CHOICE-bundle.txt
TESTS += bundles/16-SEQUENCE-bundle.txt
TESTS += bundles/17-SEQUENCE-OF-bundle.txt
TESTS += bundles/19-SET-OF-bundle.txt
EXTRA_DIST = \
random-test-driver.c \
......
......@@ -77,3 +77,4 @@ SEQUENCE { ..., null NULL, ..., one [1] NULL, two BOOLEAN, three BIT STRING (SIZ
SEQUENCE { one BOOLEAN OPTIONAL, two PrintableString (SIZE(1)), three VisibleString (SIZE(1)) DEFAULT "Z" }
SEQUENCE { one [1] BOOLEAN OPTIONAL, two [2] BOOLEAN, three [3] BOOLEAN DEFAULT TRUE, four PrintableString (SIZE(1)), five VisibleString (SIZE(1)) DEFAULT "Z" }
SEQUENCE { list SEQUENCE OF PrintableString (SIZE(1)), guard OCTET STRING (SIZE(1)) } -- RMAX=16385
......@@ -27,3 +27,8 @@ SEQUENCE (SIZE(1..2)) OF PrintableString (FROM("A".."Z"))
SEQUENCE (SIZE(1..MAX)) OF PrintableString (FROM("A".."Z"))
SEQUENCE OF PrintableString (FROM("A".."Z"))
SEQUENCE OF NULL -- RMAX=70000
SEQUENCE OF BOOLEAN -- RMAX=70000
SEQUENCE (SIZE(2..MAX)) OF BOOLEAN -- RMAX=70000
SEQUENCE OF PrintableString (SIZE(1)) --RMAX=16384
SET OF NULL
SET (SIZE(0)) OF NULL
SET (SIZE(1)) OF NULL
SET (SIZE(0..2)) OF NULL
SET (SIZE(1..2)) OF NULL
SET (SIZE(1..MAX)) OF NULL
SET OF BOOLEAN
SET (SIZE(0)) OF BOOLEAN
SET (SIZE(1)) OF BOOLEAN
SET (SIZE(0..2)) OF BOOLEAN
SET (SIZE(1..2)) OF BOOLEAN
SET (SIZE(1..MAX)) OF BOOLEAN
SET OF PrintableString (SIZE(1))
SET (SIZE(0)) OF PrintableString (SIZE(1))
SET (SIZE(1)) OF PrintableString (SIZE(1))
SET (SIZE(0..2)) OF PrintableString (SIZE(1))
SET (SIZE(1..2)) OF PrintableString (SIZE(1))
SET (SIZE(1..MAX)) OF PrintableString (SIZE(1))
SET OF PrintableString (FROM("A".."Z"))
SET (SIZE(0)) OF PrintableString (FROM("A".."Z"))
SET (SIZE(1)) OF PrintableString (FROM("A".."Z"))
SET (SIZE(0..2)) OF PrintableString (FROM("A".."Z"))
SET (SIZE(1..2)) OF PrintableString (FROM("A".."Z"))
SET (SIZE(1..MAX)) OF PrintableString (FROM("A".."Z"))
SET OF PrintableString (FROM("A".."Z"))
SET OF NULL -- RMAX=70000
SET OF BOOLEAN -- RMAX=70000
SET (SIZE(2..MAX)) OF BOOLEAN -- RMAX=70000
SET OF PrintableString (SIZE(1)) --RMAX=16384
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