Skip to content

Commit

Permalink
Merge updates to #125 to handle ANY type to allow 3GPP S1AP messages …
Browse files Browse the repository at this point in the history
…to parse
  • Loading branch information
Uri Blumenthal committed Jan 31, 2017
1 parent 94f156c commit fc2d682
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 15 deletions.
2 changes: 1 addition & 1 deletion skeletons/BOOLEAN.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ BOOLEAN_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
/*
* Extract a single bit
*/
switch(per_get_few_bits(pd, 1)) {
switch(aper_get_few_bits(pd, 1)) {
case 1:
*st = 1;
break;
Expand Down
2 changes: 1 addition & 1 deletion skeletons/INTEGER.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ INTEGER_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
ct = constraints ? &constraints->value : 0;

if(ct && ct->flags & APC_EXTENSIBLE) {
int inext = per_get_few_bits(pd, 1);
int inext = aper_get_few_bits(pd, 1);
if(inext < 0) ASN__DECODE_STARVED;
if(inext) ct = 0;
}
Expand Down
4 changes: 2 additions & 2 deletions skeletons/NativeEnumerated.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ NativeEnumerated_decode_aper(asn_codec_ctx_t *opt_codec_ctx,
ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);

if(ct->flags & APC_EXTENSIBLE) {
int inext = per_get_few_bits(pd, 1);
int inext = aper_get_few_bits(pd, 1);
if(inext < 0) {
ASN__DECODE_STARVED;
}
Expand All @@ -257,7 +257,7 @@ NativeEnumerated_decode_aper(asn_codec_ctx_t *opt_codec_ctx,
}

if(ct && ct->range_bits >= 0) {
value = per_get_few_bits(pd, ct->range_bits);
value = aper_get_few_bits(pd, ct->range_bits);
if(value < 0) {
ASN__DECODE_STARVED;
}
Expand Down
4 changes: 2 additions & 2 deletions skeletons/OCTET_STRING.c
Original file line number Diff line number Diff line change
Expand Up @@ -1691,13 +1691,13 @@ OCTET_STRING_decode_aper(asn_codec_ctx_t *opt_codec_ctx,

switch(specs->subvariant) {
default:
case ASN_OSUBV_ANY:
ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant);
RETURN(RC_FAIL);
case ASN_OSUBV_BIT:
canonical_unit_bits = unit_bits = 1;
bpc = OS__BPC_BIT;
break;
case ASN_OSUBV_ANY:
case ASN_OSUBV_STR:
canonical_unit_bits = unit_bits = 8;
if(cval->flags & APC_CONSTRAINED)
Expand Down Expand Up @@ -1731,7 +1731,7 @@ OCTET_STRING_decode_aper(asn_codec_ctx_t *opt_codec_ctx,
csiz->lower_bound, csiz->upper_bound, csiz->effective_bits);

if(csiz->flags & APC_EXTENSIBLE) {
int inext = per_get_few_bits(pd, 1);
int inext = aper_get_few_bits(pd, 1);
if(inext < 0) RETURN(RC_WMORE);
if(inext) {
csiz = &asn_DEF_OCTET_STRING_constraints.size;
Expand Down
4 changes: 2 additions & 2 deletions skeletons/constr_CHOICE.c
Original file line number Diff line number Diff line change
Expand Up @@ -1017,13 +1017,13 @@ CHOICE_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
else ct = 0;

if(ct && ct->flags & APC_EXTENSIBLE) {
value = per_get_few_bits(pd, 1);
value = aper_get_few_bits(pd, 1);
if(value < 0) ASN__DECODE_STARVED;
if(value) ct = 0; /* Not restricted */
}

if(ct && ct->range_bits >= 0) {
value = per_get_few_bits(pd, ct->range_bits);
value = aper_get_few_bits(pd, ct->range_bits);
if(value < 0) ASN__DECODE_STARVED;
ASN_DEBUG("CHOICE %s got index %d in range %d",
td->name, value, ct->range_bits);
Expand Down
8 changes: 4 additions & 4 deletions skeletons/constr_SEQUENCE.c
Original file line number Diff line number Diff line change
Expand Up @@ -1450,7 +1450,7 @@ SEQUENCE_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,

/* Handle extensions */
if(specs->ext_before >= 0) {
extpresent = per_get_few_bits(pd, 1);
extpresent = aper_get_few_bits(pd, 1);
if(extpresent < 0) ASN__DECODE_STARVED;
} else {
extpresent = 0;
Expand Down Expand Up @@ -1495,7 +1495,7 @@ SEQUENCE_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,

/* Deal with optionality */
if(elm->optional) {
int present = per_get_few_bits(&opmd, 1);
int present = aper_get_few_bits(&opmd, 1);
ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)",
td->name, elm->name, present,
(int)opmd.nboff, (int)opmd.nbits);
Expand Down Expand Up @@ -1578,7 +1578,7 @@ SEQUENCE_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
memb_ptr2 = &memb_ptr;
}

present = per_get_few_bits(&epmd, 1);
present = aper_get_few_bits(&epmd, 1);
if(present <= 0) {
if(present < 0) break; /* No more extensions */
continue;
Expand All @@ -1597,7 +1597,7 @@ SEQUENCE_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
* in this system's version of the protocol */
for(;;) {
ASN_DEBUG("Getting overflow extensions");
switch(per_get_few_bits(&epmd, 1)) {
switch(aper_get_few_bits(&epmd, 1)) {
case -1: break;
case 0: continue;
default:
Expand Down
4 changes: 2 additions & 2 deletions skeletons/constr_SET_OF.c
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ SET_OF_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
}

if(ct && ct->flags & APC_EXTENSIBLE) {
int value = per_get_few_bits(pd, 1);
int value = aper_get_few_bits(pd, 1);
if(value < 0) {
ASN__DECODE_STARVED;
}
Expand All @@ -1037,7 +1037,7 @@ SET_OF_decode_aper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,

if(ct && ct->effective_bits >= 0) {
/* X.691, #19.5: No length determinant */
nelems = per_get_few_bits(pd, ct->effective_bits);
nelems = aper_get_few_bits(pd, ct->effective_bits);
ASN_DEBUG("Preparing to fetch %ld+%lld elements from %s",
(long)nelems, ct->lower_bound, td->name);
if(nelems < 0) {
Expand Down
85 changes: 85 additions & 0 deletions skeletons/per_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,91 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
return accum;
}

int32_t
aper_get_few_bits(asn_per_data_t *pd, int nbits) {
size_t off; /* Next after last bit offset */
ssize_t nleft; /* Number of bits left in this stream */
uint32_t accum;
const uint8_t *buf;

if(nbits < 0)
return -1;

if (nbits >= 8 && aper_get_align_bits(pd) < 0)
return -1;

nleft = pd->nbits - pd->nboff;
if(nbits > nleft) {
int32_t tailv, vhead;
if(!pd->refill || nbits > 31) return -1;
/* Accumulate unused bytes before refill */
ASN_DEBUG("Obtain the rest %d bits (want %d)",
(int)nleft, (int)nbits);
tailv = per_get_few_bits(pd, nleft);
if(tailv < 0) return -1;
/* Refill (replace pd contents with new data) */
if(pd->refill(pd))
return -1;
nbits -= nleft;
vhead = per_get_few_bits(pd, nbits);
/* Combine the rest of previous pd with the head of new one */
tailv = (tailv << nbits) | vhead; /* Could == -1 */
return tailv;
}

/*
* Normalize position indicator.
*/
if(pd->nboff >= 8) {
pd->buffer += (pd->nboff >> 3);
pd->nbits -= (pd->nboff & ~0x07);
pd->nboff &= 0x07;
}
pd->moved += nbits;
pd->nboff += nbits;
off = pd->nboff;
buf = pd->buffer;

/*
* Extract specified number of bits.
*/
if(off <= 8)
accum = nbits ? (buf[0]) >> (8 - off) : 0;
else if(off <= 16)
accum = ((buf[0] << 8) + buf[1]) >> (16 - off);
else if(off <= 24)
accum = ((buf[0] << 16) + (buf[1] << 8) + buf[2]) >> (24 - off);
else if(off <= 31)
accum = ((buf[0] << 24) + (buf[1] << 16)
+ (buf[2] << 8) + (buf[3])) >> (32 - off);
else if(nbits <= 31) {
asn_per_data_t tpd = *pd;
/* Here are we with our 31-bits limit plus 1..7 bits offset. */
per_get_undo(&tpd, nbits);
/* The number of available bits in the stream allow
* for the following operations to take place without
* invoking the ->refill() function */
accum = per_get_few_bits(&tpd, nbits - 24) << 24;
accum |= per_get_few_bits(&tpd, 24);
} else {
per_get_undo(pd, nbits);
return -1;
}

accum &= (((uint32_t)1 << nbits) - 1);

ASN_DEBUG(" [PER got %2d<=%2d bits => span %d %+ld[%d..%d]:%02x (%d) => 0x%x]",
(int)nbits, (int)nleft,
(int)pd->moved,
(((long)pd->buffer) & 0xf),
(int)pd->nboff, (int)pd->nbits,
pd->buffer[0],
(int)(pd->nbits - pd->nboff),
(int)accum);

return accum;
}

/*
* Extract a large number of bits from the specified PER data pointer.
*/
Expand Down
3 changes: 2 additions & 1 deletion skeletons/per_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ int aper_get_align_bits(asn_per_data_t *pd);
* extracted due to EOD or other conditions.
*/
int32_t per_get_few_bits(asn_per_data_t *per_data, int get_nbits);

int32_t aper_get_few_bits(asn_per_data_t *per_data, int get_nbits);

/* Undo the immediately preceeding "get_few_bits" operation */
void per_get_undo(asn_per_data_t *per_data, int get_nbits);

Expand Down

0 comments on commit fc2d682

Please sign in to comment.