mirror of https://gerrit.osmocom.org/asn1c
api change uper_encode()
This commit is contained in:
parent
cb59ce69a8
commit
5615304c9a
|
@ -17,6 +17,7 @@
|
||||||
https://medium.com/@levwalkin/compile-llvm-clang-libfuzzer-b61e82718430
|
https://medium.com/@levwalkin/compile-llvm-clang-libfuzzer-b61e82718430
|
||||||
then ensure the new clang is in the way:
|
then ensure the new clang is in the way:
|
||||||
CC=clang CXX=clang++ ./configure --enable-Werror --enable-test-fuzzer
|
CC=clang CXX=clang++ ./configure --enable-Werror --enable-test-fuzzer
|
||||||
|
* uper_encode() API got new argument (breaks API compatibility).
|
||||||
|
|
||||||
FIXES:
|
FIXES:
|
||||||
* CVE-2017-12966 verified not present.
|
* CVE-2017-12966 verified not present.
|
||||||
|
|
|
@ -248,7 +248,7 @@ asn_encode_internal(const asn_codec_ctx_t *opt_codec_ctx,
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
case ATS_UNALIGNED_CANONICAL_PER:
|
case ATS_UNALIGNED_CANONICAL_PER:
|
||||||
if(td->op->uper_encoder) {
|
if(td->op->uper_encoder) {
|
||||||
er = uper_encode(td, sptr, callback, callback_key);
|
er = uper_encode(td, 0, sptr, callback, callback_key);
|
||||||
if(er.encoded == -1) {
|
if(er.encoded == -1) {
|
||||||
if(er.failed_type && er.failed_type->op->uper_encoder) {
|
if(er.failed_type && er.failed_type->op->uper_encoder) {
|
||||||
errno = EBADF; /* Structure has incorrect form. */
|
errno = EBADF; /* Structure has incorrect form. */
|
||||||
|
|
|
@ -2,16 +2,41 @@
|
||||||
#include <asn_internal.h>
|
#include <asn_internal.h>
|
||||||
#include <per_encoder.h>
|
#include <per_encoder.h>
|
||||||
|
|
||||||
static asn_enc_rval_t uper_encode_internal(const asn_TYPE_descriptor_t *td,
|
static int _uper_encode_flush_outp(asn_per_outp_t *po);
|
||||||
const asn_per_constraints_t *,
|
|
||||||
const void *sptr,
|
|
||||||
asn_app_consume_bytes_f *cb,
|
|
||||||
void *app_key);
|
|
||||||
|
|
||||||
asn_enc_rval_t
|
asn_enc_rval_t
|
||||||
uper_encode(const asn_TYPE_descriptor_t *td, const void *sptr,
|
uper_encode(const asn_TYPE_descriptor_t *td,
|
||||||
|
const asn_per_constraints_t *constraints, const void *sptr,
|
||||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||||
return uper_encode_internal(td, 0, sptr, cb, app_key);
|
asn_per_outp_t po;
|
||||||
|
asn_enc_rval_t er;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invoke type-specific encoder.
|
||||||
|
*/
|
||||||
|
if(!td || !td->op->uper_encoder)
|
||||||
|
ASN__ENCODE_FAILED; /* PER is not compiled in */
|
||||||
|
|
||||||
|
po.buffer = po.tmpspace;
|
||||||
|
po.nboff = 0;
|
||||||
|
po.nbits = 8 * sizeof(po.tmpspace);
|
||||||
|
po.output = cb;
|
||||||
|
po.op_key = app_key;
|
||||||
|
po.flushed_bytes = 0;
|
||||||
|
|
||||||
|
er = td->op->uper_encoder(td, constraints, sptr, &po);
|
||||||
|
if(er.encoded != -1) {
|
||||||
|
size_t bits_to_flush;
|
||||||
|
|
||||||
|
bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
|
||||||
|
|
||||||
|
/* Set number of bits encoded to a firm value */
|
||||||
|
er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
|
||||||
|
|
||||||
|
if(_uper_encode_flush_outp(&po)) ASN__ENCODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return er;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -35,16 +60,17 @@ static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
asn_enc_rval_t
|
asn_enc_rval_t
|
||||||
uper_encode_to_buffer(const asn_TYPE_descriptor_t *td, const void *sptr,
|
uper_encode_to_buffer(const asn_TYPE_descriptor_t *td,
|
||||||
void *buffer, size_t buffer_size) {
|
const asn_per_constraints_t *constraints,
|
||||||
|
const void *sptr, void *buffer, size_t buffer_size) {
|
||||||
enc_to_buf_arg key;
|
enc_to_buf_arg key;
|
||||||
|
|
||||||
key.buffer = buffer;
|
key.buffer = buffer;
|
||||||
key.left = buffer_size;
|
key.left = buffer_size;
|
||||||
|
|
||||||
if(td) ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name);
|
if(td) ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name);
|
||||||
|
|
||||||
return uper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key);
|
return uper_encode(td, constraints, sptr, encode_to_buffer_cb, &key);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct enc_dyn_arg {
|
typedef struct enc_dyn_arg {
|
||||||
|
@ -79,7 +105,7 @@ uper_encode_to_new_buffer(const asn_TYPE_descriptor_t *td,
|
||||||
|
|
||||||
memset(&key, 0, sizeof(key));
|
memset(&key, 0, sizeof(key));
|
||||||
|
|
||||||
er = uper_encode_internal(td, constraints, sptr, encode_dyn_cb, &key);
|
er = uper_encode(td, constraints, sptr, encode_dyn_cb, &key);
|
||||||
switch(er.encoded) {
|
switch(er.encoded) {
|
||||||
case -1:
|
case -1:
|
||||||
FREEMEM(key.buffer);
|
FREEMEM(key.buffer);
|
||||||
|
@ -123,39 +149,3 @@ _uper_encode_flush_outp(asn_per_outp_t *po) {
|
||||||
return po->output(po->tmpspace, buf - po->tmpspace, po->op_key);
|
return po->output(po->tmpspace, buf - po->tmpspace, po->op_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static asn_enc_rval_t
|
|
||||||
uper_encode_internal(const asn_TYPE_descriptor_t *td,
|
|
||||||
const asn_per_constraints_t *constraints, const void *sptr,
|
|
||||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
|
||||||
asn_per_outp_t po;
|
|
||||||
asn_enc_rval_t er;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Invoke type-specific encoder.
|
|
||||||
*/
|
|
||||||
if(!td || !td->op->uper_encoder)
|
|
||||||
ASN__ENCODE_FAILED; /* PER is not compiled in */
|
|
||||||
|
|
||||||
po.buffer = po.tmpspace;
|
|
||||||
po.nboff = 0;
|
|
||||||
po.nbits = 8 * sizeof(po.tmpspace);
|
|
||||||
po.output = cb;
|
|
||||||
po.op_key = app_key;
|
|
||||||
po.flushed_bytes = 0;
|
|
||||||
|
|
||||||
er = td->op->uper_encoder(td, constraints, sptr, &po);
|
|
||||||
if(er.encoded != -1) {
|
|
||||||
size_t bits_to_flush;
|
|
||||||
|
|
||||||
bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
|
|
||||||
|
|
||||||
/* Set number of bits encoded to a firm value */
|
|
||||||
er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
|
|
||||||
|
|
||||||
if(_uper_encode_flush_outp(&po))
|
|
||||||
ASN__ENCODE_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return er;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ struct asn_TYPE_descriptor_s; /* Forward declaration */
|
||||||
*/
|
*/
|
||||||
asn_enc_rval_t uper_encode(
|
asn_enc_rval_t uper_encode(
|
||||||
const struct asn_TYPE_descriptor_s *type_descriptor,
|
const struct asn_TYPE_descriptor_s *type_descriptor,
|
||||||
|
const asn_per_constraints_t *constraints,
|
||||||
const void *struct_ptr, /* Structure to be encoded */
|
const void *struct_ptr, /* Structure to be encoded */
|
||||||
asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */
|
asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */
|
||||||
void *app_key /* Arbitrary callback argument */
|
void *app_key /* Arbitrary callback argument */
|
||||||
|
@ -34,6 +35,7 @@ asn_enc_rval_t uper_encode(
|
||||||
*/
|
*/
|
||||||
asn_enc_rval_t uper_encode_to_buffer(
|
asn_enc_rval_t uper_encode_to_buffer(
|
||||||
const struct asn_TYPE_descriptor_s *type_descriptor,
|
const struct asn_TYPE_descriptor_s *type_descriptor,
|
||||||
|
const asn_per_constraints_t *constraints,
|
||||||
const void *struct_ptr, /* Structure to be encoded */
|
const void *struct_ptr, /* Structure to be encoded */
|
||||||
void *buffer, /* Pre-allocated buffer */
|
void *buffer, /* Pre-allocated buffer */
|
||||||
size_t buffer_size /* Initial buffer size (max) */
|
size_t buffer_size /* Initial buffer size (max) */
|
||||||
|
|
|
@ -77,7 +77,7 @@ save_object_as(PDU_t *st, enum expectation exp, enum enctype how) {
|
||||||
*/
|
*/
|
||||||
switch(how) {
|
switch(how) {
|
||||||
case AS_PER:
|
case AS_PER:
|
||||||
rval = uper_encode(&asn_DEF_PDU, st,
|
rval = uper_encode(&asn_DEF_PDU, 0, st,
|
||||||
_buf_writer, 0);
|
_buf_writer, 0);
|
||||||
if(exp == EXP_PER_NOCOMP)
|
if(exp == EXP_PER_NOCOMP)
|
||||||
assert(rval.encoded == -1);
|
assert(rval.encoded == -1);
|
||||||
|
|
|
@ -77,7 +77,7 @@ save_object_as(PDU_t *st, enum expectation exp, enum enctype how) {
|
||||||
*/
|
*/
|
||||||
switch(how) {
|
switch(how) {
|
||||||
case AS_PER:
|
case AS_PER:
|
||||||
rval = uper_encode(&asn_DEF_PDU, st,
|
rval = uper_encode(&asn_DEF_PDU, 0, st,
|
||||||
_buf_writer, 0);
|
_buf_writer, 0);
|
||||||
if(exp == EXP_PER_NOCOMP)
|
if(exp == EXP_PER_NOCOMP)
|
||||||
assert(rval.encoded == -1);
|
assert(rval.encoded == -1);
|
||||||
|
|
|
@ -66,7 +66,7 @@ save_object_as(PDU_t *st, enum enctype how) {
|
||||||
*/
|
*/
|
||||||
switch(how) {
|
switch(how) {
|
||||||
case AS_PER:
|
case AS_PER:
|
||||||
rval = uper_encode(&asn_DEF_PDU, st, _buf_writer, 0);
|
rval = uper_encode(&asn_DEF_PDU, 0, st, _buf_writer, 0);
|
||||||
assert(rval.encoded > 0);
|
assert(rval.encoded > 0);
|
||||||
fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset);
|
fprintf(stderr, "SAVED OBJECT IN SIZE %d\n", buf_offset);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -20,7 +20,7 @@ verify(int testNo, T_t *ti) {
|
||||||
ti->small32range, ti->full32range,
|
ti->small32range, ti->full32range,
|
||||||
ti->unsigned32, ti->unsplit32);
|
ti->unsigned32, ti->unsplit32);
|
||||||
|
|
||||||
er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf);
|
er = uper_encode_to_buffer(&asn_DEF_T, 0, ti, buf, sizeof buf);
|
||||||
assert(er.encoded == 8 * sizeof(buf));
|
assert(er.encoded == 8 * sizeof(buf));
|
||||||
|
|
||||||
rv = uper_decode(0, &asn_DEF_T, (void *)&to, buf, sizeof buf, 0, 0);
|
rv = uper_decode(0, &asn_DEF_T, (void *)&to, buf, sizeof buf, 0, 0);
|
||||||
|
|
|
@ -16,7 +16,7 @@ verify(int testNo, T_t *ti) {
|
||||||
unsigned char buf[2];
|
unsigned char buf[2];
|
||||||
T_t *to = 0;
|
T_t *to = 0;
|
||||||
|
|
||||||
er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf);
|
er = uper_encode_to_buffer(&asn_DEF_T, 0, ti, buf, sizeof buf);
|
||||||
fprintf(stderr, "%d IN: %d => %zd\n", testNo, ti->present, er.encoded);
|
fprintf(stderr, "%d IN: %d => %zd\n", testNo, ti->present, er.encoded);
|
||||||
assert(er.encoded >= 1 && er.encoded <= (ssize_t)(8 * sizeof(buf)));
|
assert(er.encoded >= 1 && er.encoded <= (ssize_t)(8 * sizeof(buf)));
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ verify(int testNo, T_t *ti) {
|
||||||
unsigned char buf[8];
|
unsigned char buf[8];
|
||||||
T_t *to = 0;
|
T_t *to = 0;
|
||||||
|
|
||||||
er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf);
|
er = uper_encode_to_buffer(&asn_DEF_T, 0, ti, buf, sizeof buf);
|
||||||
fprintf(stderr, "%d IN: %d => %zd\n", testNo, ti->present, er.encoded);
|
fprintf(stderr, "%d IN: %d => %zd\n", testNo, ti->present, er.encoded);
|
||||||
assert(er.encoded >= 1);
|
assert(er.encoded >= 1);
|
||||||
assert(er.encoded <= (ssize_t)(8 * sizeof(buf)));
|
assert(er.encoded <= (ssize_t)(8 * sizeof(buf)));
|
||||||
|
|
|
@ -48,7 +48,7 @@ verify(int testNo, T_t *ti) {
|
||||||
i2l(&ti->signed33), i2l(&ti->signed33ext)
|
i2l(&ti->signed33), i2l(&ti->signed33ext)
|
||||||
);
|
);
|
||||||
|
|
||||||
er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf);
|
er = uper_encode_to_buffer(&asn_DEF_T, 0, ti, buf, sizeof buf);
|
||||||
assert(er.encoded >= 33 + 42 + 33 + 1 + 33);
|
assert(er.encoded >= 33 + 42 + 33 + 1 + 33);
|
||||||
|
|
||||||
rv = uper_decode(0, &asn_DEF_T, (void *)&to, buf, sizeof buf, 0, 0);
|
rv = uper_decode(0, &asn_DEF_T, (void *)&to, buf, sizeof buf, 0, 0);
|
||||||
|
@ -83,7 +83,7 @@ NO_encode(int testNo, T_t *ti) {
|
||||||
i2l(&ti->signed33), i2l(&ti->signed33ext)
|
i2l(&ti->signed33), i2l(&ti->signed33ext)
|
||||||
);
|
);
|
||||||
|
|
||||||
er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf);
|
er = uper_encode_to_buffer(&asn_DEF_T, 0, ti, buf, sizeof buf);
|
||||||
assert(er.encoded == -1);
|
assert(er.encoded == -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ check_encode_failed(asn_TYPE_descriptor_t *td, const char *buf, size_t buflen) {
|
||||||
fprintf(stderr, "%s\n", error_buf);
|
fprintf(stderr, "%s\n", error_buf);
|
||||||
|
|
||||||
/* Second signal that something is wrong with the length */
|
/* Second signal that something is wrong with the length */
|
||||||
asn_enc_rval_t enc = uper_encode_to_buffer(td, st_in, uper_output_buffer,
|
asn_enc_rval_t enc = uper_encode_to_buffer(td, 0, st_in, uper_output_buffer,
|
||||||
sizeof(uper_output_buffer));
|
sizeof(uper_output_buffer));
|
||||||
assert(enc.encoded == -1);
|
assert(enc.encoded == -1);
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ check_round_trip_OK(asn_TYPE_descriptor_t *td, const char *buf, size_t buflen) {
|
||||||
int st_in_ct = asn_check_constraints(td, st_in, NULL, NULL);
|
int st_in_ct = asn_check_constraints(td, st_in, NULL, NULL);
|
||||||
assert(st_in_ct == 0);
|
assert(st_in_ct == 0);
|
||||||
asn_enc_rval_t enc =
|
asn_enc_rval_t enc =
|
||||||
uper_encode_to_buffer(td, st_in,
|
uper_encode_to_buffer(td, 0, st_in,
|
||||||
uper_output_buffer, sizeof(uper_output_buffer));
|
uper_output_buffer, sizeof(uper_output_buffer));
|
||||||
assert(enc.encoded > 0);
|
assert(enc.encoded > 0);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue