mirror of https://gerrit.osmocom.org/asn1c
added stack control to PER
parent
6b7fb39b61
commit
1d9e8dd64e
|
@ -19,6 +19,7 @@
|
|||
#include <errno.h> /* for errno */
|
||||
|
||||
#include <asn_application.h>
|
||||
#include <asn_internal.h> /* for _ASN_DEFAULT_STACK_MAX */
|
||||
|
||||
extern asn_TYPE_descriptor_t asn_DEF; /* ASN.1 type to be decoded */
|
||||
#ifdef ASN_PDU_COLLECTION /* Generated by asn1c: -pdu=... */
|
||||
|
@ -51,11 +52,17 @@ static enum output_format {
|
|||
OUT_NULL /* -onull: No pretty-printing */
|
||||
} oform; /* -o<format> */
|
||||
|
||||
#define DEBUG(fmt, args...) do { \
|
||||
if(!opt_debug) break; \
|
||||
fprintf(stderr, fmt, ##args); \
|
||||
fprintf(stderr, "\n"); \
|
||||
} while(0)
|
||||
/* Debug output function */
|
||||
static inline void
|
||||
DEBUG(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
if(!opt_debug) return;
|
||||
fprintf(stderr, "AD: ");
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(int ac, char **av) {
|
||||
|
@ -131,9 +138,9 @@ main(int ac, char **av) {
|
|||
break;
|
||||
case 's':
|
||||
opt_stack = atoi(optarg);
|
||||
if(opt_stack <= 0) {
|
||||
if(opt_stack < 0) {
|
||||
fprintf(stderr,
|
||||
"-s %s: Value greater than 0 expected\n",
|
||||
"-s %s: Non-negative value expected\n",
|
||||
optarg);
|
||||
exit(EX_UNAVAILABLE);
|
||||
}
|
||||
|
@ -164,8 +171,8 @@ main(int ac, char **av) {
|
|||
" -c Check ASN.1 constraints after decoding\n"
|
||||
" -d Enable debugging (-dd is even better)\n"
|
||||
" -n <num> Process files <num> times\n"
|
||||
" -s <size> Set the stack usage limit\n"
|
||||
, (long)suggested_bufsize);
|
||||
" -s <size> Set the stack usage limit (default is %d)\n"
|
||||
, (long)suggested_bufsize, _ASN_DEFAULT_STACK_MAX);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
|
@ -250,11 +257,12 @@ static int write_out(const void *buffer, size_t size, void *key) {
|
|||
return (fwrite(buffer, 1, size, fp) == size) ? 0 : -1;
|
||||
}
|
||||
|
||||
static char *buffer;
|
||||
static size_t buf_offset; /* Offset from the start */
|
||||
static char *buffer;
|
||||
static size_t buf_len; /* Length of meaningful contents */
|
||||
static size_t buf_size; /* Allocated memory */
|
||||
static off_t buf_shifted; /* Number of bytes ever shifted */
|
||||
static size_t buf_size; /* Allocated memory */
|
||||
static size_t buf_offset; /* Offset from the start */
|
||||
static off_t buf_shifted; /* Number of bytes ever shifted */
|
||||
static int buf_nreallocs; /* Number of reallocations */
|
||||
|
||||
#define bufptr (buffer + buf_offset)
|
||||
#define bufend (buffer + buf_offset + buf_len)
|
||||
|
@ -262,13 +270,13 @@ static off_t buf_shifted; /* Number of bytes ever shifted */
|
|||
/*
|
||||
* Ensure that the buffer contains at least this amount of free space.
|
||||
*/
|
||||
static void buf_extend(size_t bySize) {
|
||||
static void buf_extend(const void *data2add, size_t bySize) {
|
||||
|
||||
DEBUG("buf_extend(%ld) { o=%ld l=%ld s=%ld }",
|
||||
(long)bySize, (long)buf_offset, (long)buf_len, (long)buf_size);
|
||||
|
||||
if(buf_size >= (buf_offset + buf_len + bySize)) {
|
||||
return; /* Nothing to do */
|
||||
/* Nothing to do */
|
||||
} else if(bySize <= buf_offset) {
|
||||
DEBUG("\tContents shifted by %ld", (long)buf_offset);
|
||||
|
||||
|
@ -278,17 +286,22 @@ static void buf_extend(size_t bySize) {
|
|||
buf_offset = 0;
|
||||
} else {
|
||||
size_t newsize = (buf_size << 2) + bySize;
|
||||
void *p = realloc(buffer, newsize);
|
||||
if(p) {
|
||||
buffer = (char *)p;
|
||||
buf_size = newsize;
|
||||
|
||||
DEBUG("\tBuffer reallocated to %ld", (long)newsize);
|
||||
} else {
|
||||
void *p = malloc(newsize);
|
||||
if(!p) {
|
||||
perror("realloc()");
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
memcpy(p, buffer, buf_len);
|
||||
free(buffer);
|
||||
buffer = (char *)p;
|
||||
buf_size = newsize;
|
||||
buf_offset = 0;
|
||||
DEBUG("\tBuffer reallocated to %ld, %d time",
|
||||
(long)newsize, ++buf_nreallocs);
|
||||
}
|
||||
|
||||
memcpy(buffer + buf_offset + buf_len, data2add, bySize);
|
||||
buf_len += bySize;
|
||||
}
|
||||
|
||||
static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *fname, ssize_t suggested_bufsize) {
|
||||
|
@ -310,7 +323,7 @@ static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *f
|
|||
DEBUG("Processing file %s", fname);
|
||||
fp = fopen(fname, "r");
|
||||
} else {
|
||||
DEBUG("Processing standard input");
|
||||
DEBUG("Processing %s", "standard input");
|
||||
fname = "stdin";
|
||||
fp = stdin;
|
||||
}
|
||||
|
@ -330,8 +343,10 @@ static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *f
|
|||
fbuf_size = suggested_bufsize;
|
||||
}
|
||||
|
||||
buf_nreallocs = 0;
|
||||
buf_shifted = 0;
|
||||
buf_offset = 0;
|
||||
buf_size = 0;
|
||||
buf_len = 0;
|
||||
|
||||
/* Pretend immediate EOF */
|
||||
|
@ -339,19 +354,15 @@ static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *f
|
|||
rval.consumed = 0;
|
||||
|
||||
while((rd = fread(fbuf, 1, fbuf_size, fp)) || !feof(fp)) {
|
||||
asn_per_data_t pd;
|
||||
char *i_bptr;
|
||||
size_t i_size;
|
||||
|
||||
/*
|
||||
* Copy the data over, or use the original buffer.
|
||||
*/
|
||||
if(buf_len) {
|
||||
if(buf_size) {
|
||||
/* Append the new data into the intermediate buffer */
|
||||
buf_extend(rd);
|
||||
memcpy(bufend, fbuf, rd);
|
||||
buf_len += rd;
|
||||
|
||||
buf_extend(fbuf, rd);
|
||||
i_bptr = bufptr;
|
||||
i_size = buf_len;
|
||||
} else {
|
||||
|
@ -369,36 +380,35 @@ static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *f
|
|||
(void **)&structure, i_bptr, i_size);
|
||||
break;
|
||||
case INP_PER:
|
||||
pd.buffer = (uint8_t *)i_bptr;
|
||||
pd.nboff = 0;
|
||||
pd.nbits = i_size * 8;
|
||||
rval = pduType->uper_decoder(opt_codec_ctx, pduType, 0,
|
||||
(void **)&structure, &pd);
|
||||
rval = uper_decode(opt_codec_ctx, pduType,
|
||||
(void **)&structure, i_bptr, i_size);
|
||||
break;
|
||||
}
|
||||
DEBUG("decode(%ld) consumed %ld, code %d",
|
||||
(long)buf_len, (long)rval.consumed, rval.code);
|
||||
DEBUG("decode(%ld) consumed %ld (%ld), code %d",
|
||||
(long)buf_len, (long)rval.consumed, (long)i_size,
|
||||
rval.code);
|
||||
|
||||
if(buf_len == 0) {
|
||||
if(buf_size == 0) {
|
||||
/*
|
||||
* Switch the remainder into the intermediate buffer.
|
||||
*/
|
||||
if(rval.code != RC_FAIL && rval.consumed < rd) {
|
||||
buf_extend(rd - rval.consumed);
|
||||
memcpy(bufend,
|
||||
fbuf + rval.consumed,
|
||||
rd - rval.consumed);
|
||||
buf_len = rd - rval.consumed;
|
||||
buf_extend(fbuf + rval.consumed,
|
||||
rd - rval.consumed);
|
||||
rval.consumed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch(rval.code) {
|
||||
case RC_OK:
|
||||
DEBUG("RC_OK, finishing up");
|
||||
DEBUG("RC_OK, finishing up with %ld",
|
||||
(long)rval.consumed);
|
||||
if(fp != stdin) fclose(fp);
|
||||
return structure;
|
||||
case RC_WMORE:
|
||||
DEBUG("RC_WMORE, continuing...");
|
||||
DEBUG("RC_WMORE, continuing %ld with %ld..%ld..%ld",
|
||||
(long)rval.consumed, (long)buf_offset,
|
||||
(long)buf_len, (long)buf_size);
|
||||
/*
|
||||
* Adjust position inside the source buffer.
|
||||
*/
|
||||
|
|
|
@ -13,11 +13,13 @@ extern "C" {
|
|||
struct asn_TYPE_descriptor_s; /* Forward declaration */
|
||||
|
||||
/*
|
||||
* This structure defines a context that may be passed to every ASN.1 encoder
|
||||
* or decoder function.
|
||||
* This structure defines a set of parameters that may be passed
|
||||
* to every ASN.1 encoder or decoder function.
|
||||
* WARNING: if max_stack_size member is set, and you are calling the
|
||||
* function pointers of the asn_TYPE_descriptor_t directly,
|
||||
* this structure must be ALLOCATED ON THE STACK!
|
||||
* function pointers of the asn_TYPE_descriptor_t directly,
|
||||
* this structure must be ALLOCATED ON THE STACK!
|
||||
* If you can't always satisfy this requirement, use ber_decode(),
|
||||
* xer_decode() and uper_decode() functions instead.
|
||||
*/
|
||||
typedef struct asn_codec_ctx_s {
|
||||
/*
|
||||
|
|
|
@ -82,6 +82,28 @@ static inline void ASN_DEBUG(const char *fmt, ...) { (void)fmt; }
|
|||
if(cb(" ", 4, app_key) < 0) return -1; \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* Check stack against overflow, if limit is set.
|
||||
*/
|
||||
#define _ASN_DEFAULT_STACK_MAX (30000)
|
||||
static inline int
|
||||
_ASN_STACK_OVERFLOW_CHECK(asn_codec_ctx_t *ctx) {
|
||||
if(ctx && ctx->max_stack_size) {
|
||||
|
||||
/* ctx MUST be allocated on the stack */
|
||||
ptrdiff_t usedstack = ((char *)ctx - (char *)&ctx);
|
||||
if(usedstack > 0) usedstack = -usedstack; /* grows up! */
|
||||
|
||||
/* double negative required to avoid int wrap-around */
|
||||
if(usedstack < -(ptrdiff_t)ctx->max_stack_size) {
|
||||
ASN_DEBUG("Stack limit %ld reached",
|
||||
(long)ctx->max_stack_size);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -33,11 +33,18 @@ ber_decode(asn_codec_ctx_t *opt_codec_ctx,
|
|||
asn_codec_ctx_t s_codec_ctx;
|
||||
|
||||
/*
|
||||
* Satisfy the requirement that the codec context
|
||||
* Stack checker requires that the codec context
|
||||
* must be allocated on the stack.
|
||||
*/
|
||||
if(opt_codec_ctx && opt_codec_ctx->max_stack_size) {
|
||||
s_codec_ctx = *opt_codec_ctx;
|
||||
if(opt_codec_ctx) {
|
||||
if(opt_codec_ctx->max_stack_size) {
|
||||
s_codec_ctx = *opt_codec_ctx;
|
||||
opt_codec_ctx = &s_codec_ctx;
|
||||
}
|
||||
} else {
|
||||
/* If context is not given, be security-conscious anyway */
|
||||
memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
|
||||
s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX;
|
||||
opt_codec_ctx = &s_codec_ctx;
|
||||
}
|
||||
|
||||
|
@ -73,17 +80,8 @@ ber_check_tags(asn_codec_ctx_t *opt_codec_ctx,
|
|||
/*
|
||||
* Make sure we didn't exceed the maximum stack size.
|
||||
*/
|
||||
if(opt_codec_ctx && opt_codec_ctx->max_stack_size) {
|
||||
ptrdiff_t usedstack = ((char *)opt_codec_ctx - (char *)&size);
|
||||
/* double negative is required to avoid int wrap-around */
|
||||
if(usedstack > 0) usedstack = -usedstack;
|
||||
ASN_DEBUG("Current stack size %ld", -(long)usedstack);
|
||||
if(usedstack < -(ptrdiff_t)opt_codec_ctx->max_stack_size) {
|
||||
ASN_DEBUG("Stack limit %ld reached",
|
||||
(long)opt_codec_ctx->max_stack_size);
|
||||
RETURN(RC_FAIL);
|
||||
}
|
||||
}
|
||||
if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
|
||||
RETURN(RC_FAIL);
|
||||
|
||||
/*
|
||||
* So what does all this implicit skip stuff mean?
|
||||
|
|
|
@ -46,8 +46,8 @@ typedef asn_dec_rval_t (ber_type_decoder_f)(
|
|||
* head->last_tag_form is non-zero.
|
||||
*/
|
||||
asn_dec_rval_t ber_check_tags(
|
||||
struct asn_codec_ctx_s *opt_codec_ctx, /* optional context */
|
||||
struct asn_TYPE_descriptor_s *type_dsc,
|
||||
struct asn_codec_ctx_s *opt_codec_ctx, /* codec options */
|
||||
struct asn_TYPE_descriptor_s *type_descriptor,
|
||||
asn_struct_ctx_t *opt_ctx, /* saved decoding context */
|
||||
const void *ptr, size_t size,
|
||||
int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */
|
||||
|
|
|
@ -84,17 +84,8 @@ ber_skip_length(asn_codec_ctx_t *opt_codec_ctx,
|
|||
/*
|
||||
* Make sure we didn't exceed the maximum stack size.
|
||||
*/
|
||||
if(opt_codec_ctx && opt_codec_ctx->max_stack_size) {
|
||||
ptrdiff_t usedstack = ((char *)opt_codec_ctx - (char *)&size);
|
||||
/* double negative is required to avoid int wrap-around */
|
||||
if(usedstack > 0) usedstack = -usedstack;
|
||||
ASN_DEBUG("Current stack size %ld", -(long)usedstack);
|
||||
if(usedstack < -(ptrdiff_t)opt_codec_ctx->max_stack_size) {
|
||||
ASN_DEBUG("Stack limit %ld reached",
|
||||
(long)opt_codec_ctx->max_stack_size);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Determine the size of L in TLV.
|
||||
|
|
|
@ -31,7 +31,6 @@ ssize_t ber_fetch_length(int _is_constructed, const void *bufptr, size_t size,
|
|||
* RETURN VALUES:
|
||||
* Standard {-1,0,>0} convention.
|
||||
*/
|
||||
struct asn_codec_ctx_s; /* Forward declaration */
|
||||
ssize_t ber_skip_length(
|
||||
struct asn_codec_ctx_s *opt_codec_ctx, /* optional context */
|
||||
int _is_constructed, const void *bufptr, size_t size);
|
||||
|
|
|
@ -827,6 +827,9 @@ CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
|||
void *st = *sptr;
|
||||
int value;
|
||||
|
||||
if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
|
||||
_ASN_DECODE_FAILED;
|
||||
|
||||
/*
|
||||
* Create the target structure if it is not present already.
|
||||
*/
|
||||
|
|
|
@ -703,7 +703,8 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
|||
}
|
||||
|
||||
tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
|
||||
ASN_DEBUG("XER/SEQUENCE: tcv = %d, ph=%d", tcv, ctx->phase);
|
||||
ASN_DEBUG("XER/SEQUENCE: tcv = %d, ph=%d [%s]",
|
||||
tcv, ctx->phase, xml_tag);
|
||||
|
||||
/* Skip the extensions section */
|
||||
if(ctx->phase == 3) {
|
||||
|
@ -829,7 +830,13 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
|||
break;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Unexpected XML tag in SEQUENCE");
|
||||
ASN_DEBUG("Unexpected XML tag in SEQUENCE [%c%c%c%c%c%c]",
|
||||
size>0?((const char *)buf_ptr)[0]:'.',
|
||||
size>1?((const char *)buf_ptr)[1]:'.',
|
||||
size>2?((const char *)buf_ptr)[2]:'.',
|
||||
size>3?((const char *)buf_ptr)[3]:'.',
|
||||
size>4?((const char *)buf_ptr)[4]:'.',
|
||||
size>5?((const char *)buf_ptr)[5]:'.');
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1028,6 +1035,9 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
|||
|
||||
(void)constraints;
|
||||
|
||||
if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
|
||||
_ASN_DECODE_FAILED;
|
||||
|
||||
if(!st) {
|
||||
st = *sptr = CALLOC(1, specs->struct_size);
|
||||
if(!st) _ASN_DECODE_FAILED;
|
||||
|
|
|
@ -864,6 +864,9 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
|||
int repeat = 0;
|
||||
ssize_t nelems;
|
||||
|
||||
if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
|
||||
_ASN_DECODE_FAILED;
|
||||
|
||||
/*
|
||||
* Create the target structure if it is not present already.
|
||||
*/
|
||||
|
|
|
@ -1,2 +1,38 @@
|
|||
#include <asn_application.h>
|
||||
#include <asn_internal.h>
|
||||
#include <per_decoder.h>
|
||||
|
||||
asn_dec_rval_t
|
||||
uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size) {
|
||||
asn_codec_ctx_t s_codec_ctx;
|
||||
asn_per_data_t pd;
|
||||
|
||||
/*
|
||||
* Stack checker requires that the codec context
|
||||
* must be allocated on the stack.
|
||||
*/
|
||||
if(opt_codec_ctx) {
|
||||
if(opt_codec_ctx->max_stack_size) {
|
||||
s_codec_ctx = *opt_codec_ctx;
|
||||
opt_codec_ctx = &s_codec_ctx;
|
||||
}
|
||||
} else {
|
||||
/* If context is not given, be security-conscious anyway */
|
||||
memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
|
||||
s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX;
|
||||
opt_codec_ctx = &s_codec_ctx;
|
||||
}
|
||||
|
||||
/* Fill in the position indicator */
|
||||
pd.buffer = (const uint8_t *)buffer;
|
||||
pd.nboff = 0;
|
||||
pd.nbits = 8 * size; /* 8 is CHAR_BIT from <limits.h> */
|
||||
|
||||
/*
|
||||
* Invoke type-specific decoder.
|
||||
*/
|
||||
if(!td->uper_decoder)
|
||||
_ASN_DECODE_FAILED; /* PER is not compiled in */
|
||||
return td->uper_decoder(opt_codec_ctx, td, 0, sptr, &pd);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,18 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct asn_TYPE_descriptor_s; /* Forward declaration */
|
||||
|
||||
/*
|
||||
* Unaligned PER decoder of any ASN.1 type. May be invoked by the application.
|
||||
*/
|
||||
asn_dec_rval_t uper_decode(struct asn_codec_ctx_s *opt_codec_ctx,
|
||||
struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
|
||||
void **struct_ptr, /* Pointer to a target structure's pointer */
|
||||
const void *buffer, /* Data to be decoded */
|
||||
size_t size /* Size of data buffer */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* Pre-computed PER constraints.
|
||||
|
@ -23,7 +35,6 @@ extern "C" {
|
|||
APC_EXTENSIBLE = 0x4 /* May have extension */
|
||||
};
|
||||
typedef struct asn_per_constraint_s {
|
||||
|
||||
enum asn_per_constraint_flags flags;
|
||||
int range_bits; /* Full number of bits in the range */
|
||||
int effective_bits; /* Effective bits */
|
||||
|
@ -35,9 +46,6 @@ typedef struct asn_per_constraints_s {
|
|||
asn_per_constraint_t size;
|
||||
} asn_per_constraints_t;
|
||||
|
||||
|
||||
struct asn_TYPE_descriptor_s; /* Forward declaration */
|
||||
|
||||
/*
|
||||
* Type of the type-specific PER decoder function.
|
||||
*/
|
||||
|
|
|
@ -12,7 +12,7 @@ int32_t
|
|||
per_get_few_bits(asn_per_data_t *pd, int nbits) {
|
||||
size_t off; /* Next after last bit offset */
|
||||
uint32_t accum;
|
||||
uint8_t *buf;
|
||||
const uint8_t *buf;
|
||||
|
||||
if(nbits < 0 || pd->nboff + nbits > pd->nbits)
|
||||
return -1;
|
||||
|
|
|
@ -15,9 +15,9 @@ extern "C" {
|
|||
* This structure describes a position inside a PER bit stream.
|
||||
*/
|
||||
typedef struct asn_per_data_s {
|
||||
uint8_t *buffer; /* Pointer to the octet stream */
|
||||
size_t nboff; /* Bit offset to the meaningful bit */
|
||||
size_t nbits; /* Number of bits in the stream */
|
||||
const uint8_t *buffer; /* Pointer to the octet stream */
|
||||
size_t nboff; /* Bit offset to the meaningful bit */
|
||||
size_t nbits; /* Number of bits in the stream */
|
||||
} asn_per_data_t;
|
||||
|
||||
/*
|
||||
|
|
|
@ -16,11 +16,18 @@ xer_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
|
|||
asn_codec_ctx_t s_codec_ctx;
|
||||
|
||||
/*
|
||||
* Satisfy the requirement that the codec context
|
||||
* Stack checker requires that the codec context
|
||||
* must be allocated on the stack.
|
||||
*/
|
||||
if(opt_codec_ctx && opt_codec_ctx->max_stack_size) {
|
||||
s_codec_ctx = *opt_codec_ctx;
|
||||
if(opt_codec_ctx) {
|
||||
if(opt_codec_ctx->max_stack_size) {
|
||||
s_codec_ctx = *opt_codec_ctx;
|
||||
opt_codec_ctx = &s_codec_ctx;
|
||||
}
|
||||
} else {
|
||||
/* If context is not given, be security-conscious anyway */
|
||||
memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
|
||||
s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX;
|
||||
opt_codec_ctx = &s_codec_ctx;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,13 +14,13 @@ extern "C" {
|
|||
struct asn_TYPE_descriptor_s; /* Forward declaration */
|
||||
|
||||
/*
|
||||
* The XER decoder of any type. May be invoked by the application.
|
||||
* The XER decoder of any ASN.1 type. May be invoked by the application.
|
||||
*/
|
||||
asn_dec_rval_t xer_decode(struct asn_codec_ctx_s *opt_codec_ctx,
|
||||
struct asn_TYPE_descriptor_s *type_descriptor,
|
||||
void **struct_ptr, /* Pointer to a target structure's pointer */
|
||||
const void *buffer, /* Data to be decoded */
|
||||
size_t size /* Size of that buffer */
|
||||
size_t size /* Size of data buffer */
|
||||
);
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue