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