context is now optional
diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c
index 9609a19..c7a1cac 100644
--- a/skeletons/BOOLEAN.c
+++ b/skeletons/BOOLEAN.c
@@ -39,7 +39,6 @@
int tag_mode) {
BOOLEAN_t *st = (BOOLEAN_t *)*bool_value;
ber_dec_rval_t rval;
- ber_dec_ctx_t ctx = { 0, 0, 0, 0 };
ber_tlv_len_t length;
ber_tlv_len_t lidx;
@@ -58,8 +57,7 @@
/*
* Check tags.
*/
- rval = ber_check_tags(td, &ctx,
- buf_ptr, size, tag_mode, &length, 0);
+ rval = ber_check_tags(td, 0, buf_ptr, size, tag_mode, &length, 0);
if(rval.code != RC_OK)
return rval;
diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c
index 75782a6..73b5959 100644
--- a/skeletons/INTEGER.c
+++ b/skeletons/INTEGER.c
@@ -40,7 +40,6 @@
void **int_structure, void *buf_ptr, size_t size, int tag_mode) {
INTEGER_t *st = (INTEGER_t *)*int_structure;
ber_dec_rval_t rval;
- ber_dec_ctx_t ctx = { 0, 0, 0, 0 };
ber_tlv_len_t length;
/*
@@ -61,8 +60,7 @@
/*
* Check tags.
*/
- rval = ber_check_tags(td, &ctx,
- buf_ptr, size, tag_mode, &length, 0);
+ rval = ber_check_tags(td, 0, buf_ptr, size, tag_mode, &length, 0);
if(rval.code != RC_OK)
return rval;
diff --git a/skeletons/NativeInteger.c b/skeletons/NativeInteger.c
index b0872a2..aac5f86 100644
--- a/skeletons/NativeInteger.c
+++ b/skeletons/NativeInteger.c
@@ -47,7 +47,6 @@
void **int_ptr, void *buf_ptr, size_t size, int tag_mode) {
int *Int = (int *)*int_ptr;
ber_dec_rval_t rval;
- ber_dec_ctx_t ctx = { 0, 0, 0, 0 };
ber_tlv_len_t length;
/*
@@ -68,8 +67,7 @@
/*
* Check tags.
*/
- rval = ber_check_tags(td, &ctx,
- buf_ptr, size, tag_mode, &length, 0);
+ rval = ber_check_tags(td, 0, buf_ptr, size, tag_mode, &length, 0);
if(rval.code != RC_OK)
return rval;
diff --git a/skeletons/NativeReal.c b/skeletons/NativeReal.c
index 1566a7f..1151087 100644
--- a/skeletons/NativeReal.c
+++ b/skeletons/NativeReal.c
@@ -48,7 +48,6 @@
void **dbl_ptr, void *buf_ptr, size_t size, int tag_mode) {
double *Dbl = (double *)*dbl_ptr;
ber_dec_rval_t rval;
- ber_dec_ctx_t ctx = { 0, 0, 0, 0 };
ber_tlv_len_t length;
/*
@@ -69,8 +68,7 @@
/*
* Check tags.
*/
- rval = ber_check_tags(td, &ctx,
- buf_ptr, size, tag_mode, &length, 0);
+ rval = ber_check_tags(td, 0, buf_ptr, size, tag_mode, &length, 0);
if(rval.code != RC_OK)
return rval;
diff --git a/skeletons/ber_decoder.c b/skeletons/ber_decoder.c
index 1632bb0..3672b68 100644
--- a/skeletons/ber_decoder.c
+++ b/skeletons/ber_decoder.c
@@ -3,22 +3,25 @@
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
-#include <constr_TYPE.h>
#include <assert.h>
#undef ADVANCE
-#define ADVANCE(num_bytes) do { \
- size_t num = num_bytes; \
- ptr = ((char *)ptr) + num; \
- size -= num; \
- consumed_myself += num; \
+#define ADVANCE(num_bytes) do { \
+ size_t num = num_bytes; \
+ ptr = ((char *)ptr) + num; \
+ size -= num; \
+ consumed_myself += num; \
} while(0)
#undef RETURN
-#define RETURN(_code) do { \
- ber_dec_rval_t rval; \
- rval.code = _code; \
- rval.consumed = consumed_myself; \
- return rval; \
+#define RETURN(_code) do { \
+ ber_dec_rval_t rval; \
+ rval.code = _code; \
+ if(opt_ctx) opt_ctx->step = step; /* Save context */ \
+ if(_code == RC_OK || opt_ctx) \
+ rval.consumed = consumed_myself; \
+ else \
+ rval.consumed = 0; /* Context-free */ \
+ return rval; \
} while(0)
/*
@@ -42,7 +45,7 @@
* Check the set of <TL<TL<TL...>>> tags matches the definition.
*/
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,
ber_tlv_len_t *last_length, int *opt_tlv_form) {
ssize_t consumed_myself = 0;
@@ -53,6 +56,7 @@
ber_tlv_len_t limit_len = -1;
int expect_00_terminators = 0;
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;
/*
@@ -77,11 +81,11 @@
* it appropriately.
*/
- tagno = ctx->step /* Continuing where left previously */
+ tagno = step /* Continuing where left previously */
+ (tag_mode==1?-1:0)
;
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.
if(tag_mode == 0 && tagno == td->tags_count) {
@@ -102,23 +106,25 @@
case -1: RETURN(RC_FAIL);
case 0: RETURN(RC_WMORE);
}
+ ASN_DEBUG("Advancing %ld in ANY case",
+ (long)(tag_len + len_len));
ADVANCE(tag_len + len_len);
} else {
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.
*/
tag_len = ber_fetch_tag(ptr, size, &tlv_tag);
ASN_DEBUG("Fetching tag from {%p,%ld} %02X..%02X: "
- "len %ld, tag %s",
+ "len %ld, step %d, tag %s",
ptr, (long)size,
size?*(uint8_t *)ptr:0,
((size_t)tag_len<size&&tag_len>0)
?*((uint8_t *)ptr + tag_len):0,
- (long)tag_len,
+ (long)tag_len, step,
ber_tlv_tag_string(tlv_tag));
switch(tag_len) {
case -1: RETURN(RC_FAIL);
@@ -131,7 +137,7 @@
* If {I}, don't check anything.
* 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.
* It's just because we don't know how the tag
@@ -158,11 +164,15 @@
*/
if(tagno < (td->tags_count - 1)) {
if(tlv_constr == 0) {
+ ASN_DEBUG("tlv_constr = %d, expfail",
+ tlv_constr);
RETURN(RC_FAIL);
}
} else {
if(td->last_tag_form != tlv_constr
&& td->last_tag_form != -1) {
+ ASN_DEBUG("last_tag_form %d != %d",
+ td->last_tag_form, tlv_constr);
RETURN(RC_FAIL);
}
}
@@ -172,6 +182,7 @@
*/
len_len = ber_fetch_length(tlv_constr,
(char *)ptr + tag_len, size - tag_len, &tlv_len);
+ ASN_DEBUG("Fetchinig len = %ld", (long)len_len);
switch(len_len) {
case -1: RETURN(RC_FAIL);
case 0: RETURN(RC_WMORE);
@@ -227,7 +238,7 @@
if((ssize_t)size > limit_len) {
/*
* 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;
}