Commit 312795a2 authored by Lev Walkin's avatar Lev Walkin

OER CHOICE extensions support + fuzzing

parent 7193cf06
......@@ -238,15 +238,20 @@ CHOICE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *t
(void)CHOICE_variant_set_presence(td, st, ctx->step + 1);
if(specs->ext_start >= 0 && specs->ext_start <= ctx->step) {
/* We're in the extensions group. #20.2 requires Open Type */
ASN_DEBUG("Not implemented %s es=%d, edx=%u at %s:%d", td->name,
specs->ext_start, ctx->step, __FILE__, __LINE__);
RETURN(RC_FAIL);
ssize_t got =
oer_open_type_get(opt_codec_ctx, elm->type,
elm->encoding_constraints.oer_constraints,
memb_ptr2, ptr, size);
if(got < 0) ASN__DECODE_FAILED;
if(got == 0) ASN__DECODE_STARVED;
rval.code = RC_OK;
rval.consumed = got;
} else {
rval = elm->type->op->oer_decoder(
opt_codec_ctx, elm->type,
elm->encoding_constraints.oer_constraints, memb_ptr2, ptr,
size);
}
rval = elm->type->op->oer_decoder(opt_codec_ctx, elm->type,
elm->encoding_constraints.oer_constraints, memb_ptr2, ptr,
size);
rval.consumed += consumed_myself;
switch(rval.code) {
case RC_OK:
......@@ -319,10 +324,9 @@ CHOICE_encode_oer(asn_TYPE_descriptor_t *td,
void *memb_ptr;
ber_tlv_tag_t tag;
ssize_t tag_len;
asn_enc_rval_t er;
asn_enc_rval_t er = {0, 0, 0};
(void)constraints;
(void)specs;
if(!sptr) ASN__ENCODE_FAILED;
......@@ -355,10 +359,18 @@ CHOICE_encode_oer(asn_TYPE_descriptor_t *td,
ASN__ENCODE_FAILED;
}
er = elm->type->op->oer_encoder(elm->type, elm->encoding_constraints.oer_constraints, memb_ptr,
cb, app_key);
if(er.encoded >= 0)
er.encoded += tag_len;
if(specs->ext_start >= 0 && specs->ext_start <= (present-1)) {
ssize_t encoded = oer_open_type_put(elm->type,
elm->encoding_constraints.oer_constraints,
memb_ptr, cb, app_key);
if(encoded < 0) ASN__ENCODE_FAILED;
er.encoded = tag_len + encoded;
} else {
er = elm->type->op->oer_encoder(
elm->type, elm->encoding_constraints.oer_constraints, memb_ptr, cb,
app_key);
if(er.encoded >= 0) er.encoded += tag_len;
}
return er;
}
......
......@@ -64,6 +64,8 @@ oer_open_type_get(const asn_codec_ctx_t *opt_codec_ctx,
asn_dec_rval_t dr;
size_t container_len = 0;
ssize_t len_len;
enum asn_struct_free_method dispose_method =
(*struct_ptr) ? ASFM_FREE_UNDERLYING_AND_RESET : ASFM_FREE_EVERYTHING;
/* Get the size of a length determinant */
len_len = oer_fetch_length(bufptr, size, &container_len);
......@@ -86,8 +88,7 @@ oer_open_type_get(const asn_codec_ctx_t *opt_codec_ctx,
return len_len + container_len;
} else {
/* Even if RC_WMORE, we can't get more data into a closed container. */
ASN_STRUCT_FREE(*td, *struct_ptr);
*struct_ptr = 0;
td->op->free_struct(td, *struct_ptr, dispose_method);
return -1;
}
}
......
......@@ -41,8 +41,8 @@ typedef asn_dec_rval_t(oer_type_decoder_f)(
/*
* Swallow the Open Type (X.696 (08/2015), #30) into /dev/null.
* RETURN VALUES:
* 0: More data expected than bufptr contains.
* -1: Fatal error deciphering length.
* 0: More data expected than bufptr contains.
* >0: Number of bytes used from bufptr.
*/
ssize_t oer_open_type_skip(const void *bufptr, size_t size);
......
......@@ -109,3 +109,34 @@ oer_encode_primitive(asn_TYPE_descriptor_t *td,
}
}
static int
oer__count_bytes(const void *buffer, size_t size, void *bytes_ptr) {
size_t *bytes = bytes_ptr;
*bytes += size;
return 0;
}
ssize_t
oer_open_type_put(asn_TYPE_descriptor_t *td,
const asn_oer_constraints_t *constraints,
void *sptr, asn_app_consume_bytes_f *cb,
void *app_key) {
size_t serialized_byte_count = 0;
asn_enc_rval_t er;
ssize_t len_len;
er = td->op->oer_encoder(td, constraints, sptr, oer__count_bytes,
&serialized_byte_count);
if(er.encoded == -1) return -1;
assert(serialized_byte_count == er.encoded);
len_len = oer_serialize_length(serialized_byte_count, cb, app_key);
if(len_len == -1) return -1;
er = td->op->oer_encoder(td, constraints, sptr, cb, app_key);
if(er.encoded == -1) return -1;
assert(serialized_byte_count == er.encoded);
return er.encoded + len_len;
}
......@@ -45,6 +45,18 @@ typedef asn_enc_rval_t(oer_type_encoder_f)(
void *app_key /* Arbitrary callback argument */
);
/*
* Write out the Open Type (X.696 (08/2015), #30).
* RETURN VALUES:
* -1: Fatal error encoding the type.
* >=0: Number of bytes serialized.
*/
ssize_t oer_open_type_put(struct asn_TYPE_descriptor_s *td,
const asn_oer_constraints_t *constraints,
void *struct_ptr,
asn_app_consume_bytes_f *consume_bytes_cb,
void *app_key);
/*
* Length-prefixed buffer encoding for primitive types.
......
CHOICE { null NULL }
CHOICE { null NULL, ... }
CHOICE { one NULL, two [2] NULL }
CHOICE { one NULL, two [2] NULL, ... }
CHOICE { one NULL, ..., two [2] NULL }
CHOICE { one NULL, two [2] NULL, ..., three [3] NULL }
CHOICE { one NULL, ..., two [2] NULL, three [3] NULL }
CHOICE { one BOOLEAN, ..., two [2] BOOLEAN, three [3] BOOLEAN }
CHOICE { one BOOLEAN, two BIT STRING (SIZE(1..3)) }
CHOICE { ..., one BOOLEAN, two BIT STRING (SIZE(1..3)) }
CHOICE { one NULL, two BOOLEAN, three BIT STRING (SIZE(1..3)) }
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