asn_dec_rval_t SEQUENCE_decode_uper(Allocator * allocator, asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics; void *st = *sptr; /* Target structure. */ int extpresent; /* Extension additions are present */ uint8_t *opres; /* Presence of optional root members */ asn_per_data_t opmd; asn_dec_rval_t rv; int edx; (void)constraints; if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx)) _ASN_DECODE_FAILED; if(!st) { st = *sptr = CXX_ALLOC_WRAP CALLOC(1, specs->struct_size); if(!st) _ASN_DECODE_FAILED; } ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name); /* Handle extensions */ if(specs->ext_before >= 0) { extpresent = per_get_few_bits(pd, 1); if(extpresent < 0) _ASN_DECODE_STARVED; } else { extpresent = 0; } /* Prepare a place and read-in the presence bitmap */ memset(&opmd, 0, sizeof(opmd)); if(specs->roms_count) { opres = (uint8_t *)CXX_ALLOC_WRAP MALLOC(((specs->roms_count + 7) >> 3) + 1); if(!opres) _ASN_DECODE_FAILED; /* Get the presence map */ if(per_get_many_bits(pd, opres, 0, specs->roms_count)) { CXX_ALLOC_WRAP FREEMEM(opres); _ASN_DECODE_STARVED; } opmd.buffer = opres; opmd.nbits = specs->roms_count; ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)", td->name, specs->roms_count, *opres); } else {
static asn_dec_rval_t uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { asn_dec_rval_t rv; ssize_t chunk_bytes; int repeat; uint8_t *buf = 0; size_t bufLen = 0; size_t bufSize = 0; asn_per_data_t spd; size_t padding; _ASN_STACK_OVERFLOW_CHECK(ctx); ASN_DEBUG("Getting open type %s...", td->name); do { chunk_bytes = uper_get_length(pd, -1, &repeat); if(chunk_bytes < 0) { FREEMEM(buf); _ASN_DECODE_STARVED; } if(bufLen + chunk_bytes > bufSize) { void *ptr; bufSize = chunk_bytes + (bufSize << 2); ptr = REALLOC(buf, bufSize); if(!ptr) { FREEMEM(buf); _ASN_DECODE_FAILED; } buf = ptr; } if(per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) { FREEMEM(buf); _ASN_DECODE_STARVED; } bufLen += chunk_bytes; } while(repeat); ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name, (long)bufLen); memset(&spd, 0, sizeof(spd)); spd.buffer = buf; spd.nbits = bufLen << 3; ASN_DEBUG_INDENT_ADD(+4); rv = td->uper_decoder(ctx, td, constraints, sptr, &spd); ASN_DEBUG_INDENT_ADD(-4); if(rv.code == RC_OK) { /* Check padding validity */ padding = spd.nbits - spd.nboff; if ((padding < 8 || /* X.691#10.1.3 */ (spd.nboff == 0 && spd.nbits == 8 && spd.buffer == buf)) && per_get_few_bits(&spd, padding) == 0) { /* Everything is cool */ FREEMEM(buf); return rv; } FREEMEM(buf); if(padding >= 8) { ASN_DEBUG("Too large padding %d in open type", (int)padding); _ASN_DECODE_FAILED; } else { ASN_DEBUG("Non-zero padding"); _ASN_DECODE_FAILED; } } else { FREEMEM(buf); /* rv.code could be RC_WMORE, nonsense in this context */ rv.code = RC_FAIL; /* Noone would give us more */ } return rv; }