Commit 5ccf1eb5 authored by Lev Walkin's avatar Lev Walkin

context is now optional

parent 52559a2e
...@@ -39,7 +39,6 @@ BOOLEAN_decode_ber(asn1_TYPE_descriptor_t *td, ...@@ -39,7 +39,6 @@ BOOLEAN_decode_ber(asn1_TYPE_descriptor_t *td,
int tag_mode) { int tag_mode) {
BOOLEAN_t *st = (BOOLEAN_t *)*bool_value; BOOLEAN_t *st = (BOOLEAN_t *)*bool_value;
ber_dec_rval_t rval; ber_dec_rval_t rval;
ber_dec_ctx_t ctx = { 0, 0, 0, 0 };
ber_tlv_len_t length; ber_tlv_len_t length;
ber_tlv_len_t lidx; ber_tlv_len_t lidx;
...@@ -58,8 +57,7 @@ BOOLEAN_decode_ber(asn1_TYPE_descriptor_t *td, ...@@ -58,8 +57,7 @@ BOOLEAN_decode_ber(asn1_TYPE_descriptor_t *td,
/* /*
* Check tags. * Check tags.
*/ */
rval = ber_check_tags(td, &ctx, rval = ber_check_tags(td, 0, buf_ptr, size, tag_mode, &length, 0);
buf_ptr, size, tag_mode, &length, 0);
if(rval.code != RC_OK) if(rval.code != RC_OK)
return rval; return rval;
......
...@@ -40,7 +40,6 @@ INTEGER_decode_ber(asn1_TYPE_descriptor_t *td, ...@@ -40,7 +40,6 @@ INTEGER_decode_ber(asn1_TYPE_descriptor_t *td,
void **int_structure, void *buf_ptr, size_t size, int tag_mode) { void **int_structure, void *buf_ptr, size_t size, int tag_mode) {
INTEGER_t *st = (INTEGER_t *)*int_structure; INTEGER_t *st = (INTEGER_t *)*int_structure;
ber_dec_rval_t rval; ber_dec_rval_t rval;
ber_dec_ctx_t ctx = { 0, 0, 0, 0 };
ber_tlv_len_t length; ber_tlv_len_t length;
/* /*
...@@ -61,8 +60,7 @@ INTEGER_decode_ber(asn1_TYPE_descriptor_t *td, ...@@ -61,8 +60,7 @@ INTEGER_decode_ber(asn1_TYPE_descriptor_t *td,
/* /*
* Check tags. * Check tags.
*/ */
rval = ber_check_tags(td, &ctx, rval = ber_check_tags(td, 0, buf_ptr, size, tag_mode, &length, 0);
buf_ptr, size, tag_mode, &length, 0);
if(rval.code != RC_OK) if(rval.code != RC_OK)
return rval; return rval;
......
...@@ -47,7 +47,6 @@ NativeInteger_decode_ber(asn1_TYPE_descriptor_t *td, ...@@ -47,7 +47,6 @@ NativeInteger_decode_ber(asn1_TYPE_descriptor_t *td,
void **int_ptr, void *buf_ptr, size_t size, int tag_mode) { void **int_ptr, void *buf_ptr, size_t size, int tag_mode) {
int *Int = (int *)*int_ptr; int *Int = (int *)*int_ptr;
ber_dec_rval_t rval; ber_dec_rval_t rval;
ber_dec_ctx_t ctx = { 0, 0, 0, 0 };
ber_tlv_len_t length; ber_tlv_len_t length;
/* /*
...@@ -68,8 +67,7 @@ NativeInteger_decode_ber(asn1_TYPE_descriptor_t *td, ...@@ -68,8 +67,7 @@ NativeInteger_decode_ber(asn1_TYPE_descriptor_t *td,
/* /*
* Check tags. * Check tags.
*/ */
rval = ber_check_tags(td, &ctx, rval = ber_check_tags(td, 0, buf_ptr, size, tag_mode, &length, 0);
buf_ptr, size, tag_mode, &length, 0);
if(rval.code != RC_OK) if(rval.code != RC_OK)
return rval; return rval;
......
...@@ -48,7 +48,6 @@ NativeReal_decode_ber(asn1_TYPE_descriptor_t *td, ...@@ -48,7 +48,6 @@ NativeReal_decode_ber(asn1_TYPE_descriptor_t *td,
void **dbl_ptr, void *buf_ptr, size_t size, int tag_mode) { void **dbl_ptr, void *buf_ptr, size_t size, int tag_mode) {
double *Dbl = (double *)*dbl_ptr; double *Dbl = (double *)*dbl_ptr;
ber_dec_rval_t rval; ber_dec_rval_t rval;
ber_dec_ctx_t ctx = { 0, 0, 0, 0 };
ber_tlv_len_t length; ber_tlv_len_t length;
/* /*
...@@ -69,8 +68,7 @@ NativeReal_decode_ber(asn1_TYPE_descriptor_t *td, ...@@ -69,8 +68,7 @@ NativeReal_decode_ber(asn1_TYPE_descriptor_t *td,
/* /*
* Check tags. * Check tags.
*/ */
rval = ber_check_tags(td, &ctx, rval = ber_check_tags(td, 0, buf_ptr, size, tag_mode, &length, 0);
buf_ptr, size, tag_mode, &length, 0);
if(rval.code != RC_OK) if(rval.code != RC_OK)
return rval; return rval;
......
...@@ -3,22 +3,25 @@ ...@@ -3,22 +3,25 @@
* Redistribution and modifications are permitted subject to BSD license. * Redistribution and modifications are permitted subject to BSD license.
*/ */
#include <asn_internal.h> #include <asn_internal.h>
#include <constr_TYPE.h>
#include <assert.h> #include <assert.h>
#undef ADVANCE #undef ADVANCE
#define ADVANCE(num_bytes) do { \ #define ADVANCE(num_bytes) do { \
size_t num = num_bytes; \ size_t num = num_bytes; \
ptr = ((char *)ptr) + num; \ ptr = ((char *)ptr) + num; \
size -= num; \ size -= num; \
consumed_myself += num; \ consumed_myself += num; \
} while(0) } while(0)
#undef RETURN #undef RETURN
#define RETURN(_code) do { \ #define RETURN(_code) do { \
ber_dec_rval_t rval; \ ber_dec_rval_t rval; \
rval.code = _code; \ rval.code = _code; \
rval.consumed = consumed_myself; \ if(opt_ctx) opt_ctx->step = step; /* Save context */ \
return rval; \ if(_code == RC_OK || opt_ctx) \
rval.consumed = consumed_myself; \
else \
rval.consumed = 0; /* Context-free */ \
return rval; \
} while(0) } while(0)
/* /*
...@@ -42,7 +45,7 @@ ber_decode(asn1_TYPE_descriptor_t *type_descriptor, ...@@ -42,7 +45,7 @@ ber_decode(asn1_TYPE_descriptor_t *type_descriptor,
* Check the set of <TL<TL<TL...>>> tags matches the definition. * Check the set of <TL<TL<TL...>>> tags matches the definition.
*/ */
ber_dec_rval_t ber_dec_rval_t
ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx, ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *opt_ctx,
void *ptr, size_t size, int tag_mode, void *ptr, size_t size, int tag_mode,
ber_tlv_len_t *last_length, int *opt_tlv_form) { ber_tlv_len_t *last_length, int *opt_tlv_form) {
ssize_t consumed_myself = 0; ssize_t consumed_myself = 0;
...@@ -53,6 +56,7 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx, ...@@ -53,6 +56,7 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx,
ber_tlv_len_t limit_len = -1; ber_tlv_len_t limit_len = -1;
int expect_00_terminators = 0; int expect_00_terminators = 0;
int tlv_constr = -1; /* If CHOICE, opt_tlv_form is not given */ int tlv_constr = -1; /* If CHOICE, opt_tlv_form is not given */
int step = opt_ctx ? opt_ctx->step : 0; /* Where we left previously */
int tagno; int tagno;
/* /*
...@@ -77,11 +81,11 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx, ...@@ -77,11 +81,11 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx,
* it appropriately. * it appropriately.
*/ */
tagno = ctx->step /* Continuing where left previously */ tagno = step /* Continuing where left previously */
+ (tag_mode==1?-1:0) + (tag_mode==1?-1:0)
; ;
ASN_DEBUG("ber_check_tags(%s, size=%ld, tm=%d, step=%d, tagno=%d)", ASN_DEBUG("ber_check_tags(%s, size=%ld, tm=%d, step=%d, tagno=%d)",
td->name, (long)size, tag_mode, ctx->step, tagno); td->name, (long)size, tag_mode, step, tagno);
//assert(td->tags_count >= 1); ?May not be the case for CHOICE or ANY. //assert(td->tags_count >= 1); ?May not be the case for CHOICE or ANY.
if(tag_mode == 0 && tagno == td->tags_count) { if(tag_mode == 0 && tagno == td->tags_count) {
...@@ -102,23 +106,25 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx, ...@@ -102,23 +106,25 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx,
case -1: RETURN(RC_FAIL); case -1: RETURN(RC_FAIL);
case 0: RETURN(RC_WMORE); case 0: RETURN(RC_WMORE);
} }
ASN_DEBUG("Advancing %ld in ANY case",
(long)(tag_len + len_len));
ADVANCE(tag_len + len_len); ADVANCE(tag_len + len_len);
} else { } else {
assert(tagno < td->tags_count); /* At least one loop */ assert(tagno < td->tags_count); /* At least one loop */
} }
for((void)tagno; tagno < td->tags_count; tagno++, ctx->step++) { for((void)tagno; tagno < td->tags_count; tagno++, step++) {
/* /*
* Fetch and process T from TLV. * Fetch and process T from TLV.
*/ */
tag_len = ber_fetch_tag(ptr, size, &tlv_tag); tag_len = ber_fetch_tag(ptr, size, &tlv_tag);
ASN_DEBUG("Fetching tag from {%p,%ld} %02X..%02X: " ASN_DEBUG("Fetching tag from {%p,%ld} %02X..%02X: "
"len %ld, tag %s", "len %ld, step %d, tag %s",
ptr, (long)size, ptr, (long)size,
size?*(uint8_t *)ptr:0, size?*(uint8_t *)ptr:0,
((size_t)tag_len<size&&tag_len>0) ((size_t)tag_len<size&&tag_len>0)
?*((uint8_t *)ptr + tag_len):0, ?*((uint8_t *)ptr + tag_len):0,
(long)tag_len, (long)tag_len, step,
ber_tlv_tag_string(tlv_tag)); ber_tlv_tag_string(tlv_tag));
switch(tag_len) { switch(tag_len) {
case -1: RETURN(RC_FAIL); case -1: RETURN(RC_FAIL);
...@@ -131,7 +137,7 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx, ...@@ -131,7 +137,7 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx,
* If {I}, don't check anything. * If {I}, don't check anything.
* If {I,B,C}, check B and C unless we're at I. * If {I,B,C}, check B and C unless we're at I.
*/ */
if(tag_mode != 0 && ctx->step == 0) { if(tag_mode != 0 && step == 0) {
/* /*
* We don't expect tag to match here. * We don't expect tag to match here.
* It's just because we don't know how the tag * It's just because we don't know how the tag
...@@ -158,11 +164,15 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx, ...@@ -158,11 +164,15 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx,
*/ */
if(tagno < (td->tags_count - 1)) { if(tagno < (td->tags_count - 1)) {
if(tlv_constr == 0) { if(tlv_constr == 0) {
ASN_DEBUG("tlv_constr = %d, expfail",
tlv_constr);
RETURN(RC_FAIL); RETURN(RC_FAIL);
} }
} else { } else {
if(td->last_tag_form != tlv_constr if(td->last_tag_form != tlv_constr
&& td->last_tag_form != -1) { && td->last_tag_form != -1) {
ASN_DEBUG("last_tag_form %d != %d",
td->last_tag_form, tlv_constr);
RETURN(RC_FAIL); RETURN(RC_FAIL);
} }
} }
...@@ -172,6 +182,7 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx, ...@@ -172,6 +182,7 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx,
*/ */
len_len = ber_fetch_length(tlv_constr, len_len = ber_fetch_length(tlv_constr,
(char *)ptr + tag_len, size - tag_len, &tlv_len); (char *)ptr + tag_len, size - tag_len, &tlv_len);
ASN_DEBUG("Fetchinig len = %ld", (long)len_len);
switch(len_len) { switch(len_len) {
case -1: RETURN(RC_FAIL); case -1: RETURN(RC_FAIL);
case 0: RETURN(RC_WMORE); case 0: RETURN(RC_WMORE);
...@@ -227,7 +238,7 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx, ...@@ -227,7 +238,7 @@ ber_check_tags(asn1_TYPE_descriptor_t *td, ber_dec_ctx_t *ctx,
if((ssize_t)size > limit_len) { if((ssize_t)size > limit_len) {
/* /*
* Make sure that we won't consume more bytes * Make sure that we won't consume more bytes
* from the large buffer than the inferred limit. * from the parent frame than the inferred limit.
*/ */
size = limit_len; size = limit_len;
} }
......
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