diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c index d1b08741fe4ac463f42b67f9f9fa8580b889d1a6..a9c591d91334748d16c389ff7baacf4ba7e8c50e 100644 --- a/skeletons/OCTET_STRING.c +++ b/skeletons/OCTET_STRING.c @@ -1103,26 +1103,34 @@ OCTET_STRING__decode_xer(asn_codec_ctx_t *opt_codec_ctx, (void *struct_ptr, void *chunk_buf, size_t chunk_size, int have_more) ) { + OCTET_STRING_t *st = *sptr; asn_OCTET_STRING_specifics_t *specs = td->specifics ? (asn_OCTET_STRING_specifics_t *)td->specifics : &asn_DEF_OCTET_STRING_specs; const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; asn_struct_ctx_t *ctx; /* Per-structure parser context */ + asn_dec_rval_t rval; /* Return value from the decoder */ + int st_allocated; /* * Create the string if does not exist. */ - if(!*sptr) { - OCTET_STRING_t *st; + if(!st) { st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size); - if(st) st->buf = (uint8_t *)CALLOC(1, 1); *sptr = (void *)st; - if(!st || !st->buf) { - asn_dec_rval_t rval; - if(*sptr) FREEMEM(*sptr); - rval.code = RC_FAIL; - rval.consumed = 0; - return rval; + if(!st) goto sta_failed; + st_allocated = 1; + } else st_allocated = 0; + if(!st->buf) { + /* This is separate from above section */ + st->buf = (uint8_t *)CALLOC(1, 1); + if(!st->buf) { + if(st_allocated) { + *sptr = 0; + goto stb_failed; + } else { + goto sta_failed; + } } } @@ -1131,6 +1139,13 @@ OCTET_STRING__decode_xer(asn_codec_ctx_t *opt_codec_ctx, return xer_decode_general(opt_codec_ctx, ctx, *sptr, xml_tag, buf_ptr, size, opt_unexpected_tag_decoder, body_receiver); + +stb_failed: + FREEMEM(st); +sta_failed: + rval.code = RC_FAIL; + rval.consumed = 0; + return rval; } /* diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c index 40e99e5d90db21daa1f55d561a4115be1935c64f..0222abfcb4da1e003bbd9326b38f47333c511f12 100644 --- a/skeletons/constr_CHOICE.c +++ b/skeletons/constr_CHOICE.c @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>. + * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include <asn_internal.h> @@ -539,7 +540,6 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr, } } -#undef ADVANCE /* Just in case */ #undef XER_ADVANCE #define XER_ADVANCE(num_bytes) do { \ size_t num = num_bytes; \ @@ -548,6 +548,9 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr, consumed_myself += num; \ } while(0) +/* + * Decode the XER (XML) data. + */ asn_dec_rval_t CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **struct_ptr, const char *opt_mname, @@ -564,7 +567,7 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void *st = *struct_ptr; /* Target structure. */ asn_struct_ctx_t *ctx; /* Decoder context */ - asn_dec_rval_t rval; + asn_dec_rval_t rval; /* Return value of a decoder */ ssize_t consumed_myself = 0; /* Consumed bytes from ptr */ int xer_state; /* XER low level parsing context */ int edx; /* Element index */ @@ -590,9 +593,7 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, * Phase 2: Processing inner type. * Phase 3: Only waiting for closing tag */ - - if(ctx->phase > 3) RETURN(RC_FAIL); - for(xer_state = ctx->left, edx = ctx->step;;) { + for(xer_state = ctx->left, edx = ctx->step; ctx->phase <= 3;) { pxer_chunk_type_e ch_type; /* XER chunk type */ ssize_t ch_size; /* Chunk size */ xer_check_tag_e tcv; /* Tag check value */ @@ -617,12 +618,19 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, memb_ptr2 = &memb_ptr; } + /* Start/Continue decoding the inner member */ tmprval = elm->type->xer_decoder(opt_codec_ctx, elm->type, memb_ptr2, elm->name, buf_ptr, size); XER_ADVANCE(tmprval.consumed); + ASN_DEBUG("XER/CHOICE: itdf: code=%d, xs=%d", tmprval.code, xer_state); if(tmprval.code != RC_OK) RETURN(tmprval.code); + assert(_fetch_present_idx(st, + specs->pres_offset, specs->pres_size) == 0); + /* Record what we've got */ + _set_present_idx(st, + specs->pres_offset, specs->pres_size, edx + 1); ctx->left = xer_state = 0; /* New, clean state */ ctx->phase = 3; /* Fall through */ @@ -648,25 +656,22 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } } - tcv = xer_check_tag(buf_ptr, size, xml_tag); + tcv = xer_check_tag(buf_ptr, ch_size, xml_tag); + printf("XER/CHOICE tcv=%d ph=%d\n", tcv, ctx->phase); switch(tcv) { case XCT_BOTH: - if(ctx->phase == 3) - break; + break; /* No CHOICE? */ case XCT_CLOSING: - if(ctx->phase == 0) + if(ctx->phase != 3) break; XER_ADVANCE(ch_size); - ctx->phase = 4; + ctx->phase = 4; /* Phase out */ RETURN(RC_OK); case XCT_OPENING: if(ctx->phase == 0) { XER_ADVANCE(ch_size); ctx->phase = 1; /* Processing body phase */ continue; - } else if(ctx->phase == 3) { - /* But we're waiting for closing! */ - break; } /* Fall through */ case XCT_UNEXPECTED: @@ -675,11 +680,11 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, break; /* Really unexpected */ /* - * Search which member corresponds to this tag. + * Search which inner member corresponds to this tag. */ for(edx = 0; edx < td->elements_count; edx++) { elm = &td->elements[edx]; - tcv = xer_check_tag(buf_ptr, size, elm->name); + tcv = xer_check_tag(buf_ptr,ch_size,elm->name); switch(tcv) { case XCT_BOTH: case XCT_OPENING: @@ -704,7 +709,7 @@ CHOICE_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 CHOICE"); break; } diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c index bac424453f5f97d178f64f5b1ad7c114ea2c3118..01fc8a95500f09d194ab613831333412eec9e963 100644 --- a/skeletons/constr_SEQUENCE.c +++ b/skeletons/constr_SEQUENCE.c @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>. + * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include <asn_internal.h> @@ -588,7 +589,7 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, return erval; } -#undef ADVANCE /* Just in case */ + #undef XER_ADVANCE #define XER_ADVANCE(num_bytes) do { \ size_t num = num_bytes; \ @@ -597,6 +598,9 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, consumed_myself += num; \ } while(0) +/* + * Decode the XER (XML) data. + */ asn_dec_rval_t SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **struct_ptr, const char *opt_mname, @@ -604,17 +608,18 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, /* * Bring closer parts of structure description. */ - asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics; + asn_SEQUENCE_specifics_t *specs + = (asn_SEQUENCE_specifics_t *)td->specifics; asn_TYPE_member_t *elements = td->elements; const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; /* - * Parts of the structure being constructed. + * ... and parts of the structure being constructed. */ void *st = *struct_ptr; /* Target structure. */ asn_struct_ctx_t *ctx; /* Decoder context */ - asn_dec_rval_t rval; + asn_dec_rval_t rval; /* Return value from a decoder */ ssize_t consumed_myself = 0; /* Consumed bytes from ptr */ int xer_state; /* XER low level parsing context */ int edx; /* Element index */ @@ -639,16 +644,14 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, * Phase 1: Processing body and reacting on closing tag. * Phase 2: Processing inner type. */ - - if(ctx->phase > 2) RETURN(RC_FAIL); - for(xer_state = ctx->left, edx = ctx->step;;) { + for(xer_state = ctx->left, edx = ctx->step; ctx->phase <= 2;) { pxer_chunk_type_e ch_type; /* XER chunk type */ ssize_t ch_size; /* Chunk size */ xer_check_tag_e tcv; /* Tag check value */ asn_TYPE_member_t *elm; /* - * Go inside the member. + * Go inside the inner member of a sequence. */ if(ctx->phase == 2) { asn_dec_rval_t tmprval; @@ -666,15 +669,18 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, memb_ptr2 = &memb_ptr; } + /* Invoke the inner type decoder, m.b. multiple times */ tmprval = elm->type->xer_decoder(opt_codec_ctx, elm->type, memb_ptr2, elm->name, buf_ptr, size); XER_ADVANCE(tmprval.consumed); if(tmprval.code != RC_OK) RETURN(tmprval.code); - ctx->phase = 1; + ctx->phase = 1; /* Back to body processing */ ctx->left = xer_state = 0; /* New, clean state */ ctx->step = ++edx; + ASN_DEBUG("XER/SEQUENCE phase => %d, step => %d", + ctx->phase, ctx->step); /* Fall through */ } @@ -698,11 +704,11 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, } } - tcv = xer_check_tag(buf_ptr, size, xml_tag); + tcv = xer_check_tag(buf_ptr, ch_size, xml_tag); + ASN_DEBUG("XER/SEQUENCE: tcv = %d, ph=%d", tcv, ctx->phase); switch(tcv) { case XCT_CLOSING: if(ctx->phase == 0) break; - XER_ADVANCE(ch_size); ctx->phase = 0; /* Fall through */ case XCT_BOTH: @@ -720,7 +726,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ) { XER_ADVANCE(ch_size); ctx->phase = 3; /* Phase out */ - continue; + RETURN(RC_OK); } else { ASN_DEBUG("Premature end of XER SEQUENCE"); RETURN(RC_FAIL); @@ -738,7 +744,9 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, int edx_end; int n; - if(!ctx->phase + ASN_DEBUG("XER/SEQUENCE: tcv=%d, ph=%d", + tcv, ctx->phase); + if(ctx->phase != 1 || edx >= td->elements_count) break; /* Really unexpected */ @@ -748,7 +756,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, edx_end = edx + elements[edx].optional + 1; for(n = edx; n < edx_end; n++) { elm = &td->elements[n]; - tcv = xer_check_tag(buf_ptr, size, elm->name); + tcv = xer_check_tag(buf_ptr,ch_size,elm->name); switch(tcv) { case XCT_BOTH: case XCT_OPENING: @@ -778,7 +786,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, break; } - ctx->phase = 3; /* Phase out, just in case */ + ctx->phase = 3; /* "Phase out" on hard failure */ RETURN(RC_FAIL); } diff --git a/skeletons/xer_decoder.c b/skeletons/xer_decoder.c index db27a4971398aa25a2f07aa0701bbe8de1fc7027..79a6bccce4e449cc8f9b7426faecf7dc27e0ec9f 100644 --- a/skeletons/xer_decoder.c +++ b/skeletons/xer_decoder.c @@ -55,9 +55,10 @@ xer_next_token(int *stateContext, void *buffer, size_t size, pxer_chunk_type_e *ch_type) { struct xer__cb_arg arg; ssize_t ret; + int new_stateContext = *stateContext; arg.callback_not_invoked = 1; - ret = pxml_parse(stateContext, buffer, size, xer__token_cb, &arg); + ret = pxml_parse(&new_stateContext, buffer, size, xer__token_cb, &arg); if(ret < 0) return -1; if(arg.callback_not_invoked) { assert(ret == 0); /* No data was consumed */ @@ -84,6 +85,7 @@ xer_next_token(int *stateContext, void *buffer, size_t size, break; } + *stateContext = new_stateContext; /* Update the context */ return arg.chunk_size; } @@ -98,6 +100,8 @@ xer_check_tag(const void *buf_ptr, int size, const char *need_tag) { xer_check_tag_e ct = XCT_OPENING; if(size < 2 || buf[0] != LANGLE || buf[size-1] != RANGLE) { + if(size >= 2) + ASN_DEBUG("Broken XML tag: \"%c...%c\"", buf[0], buf[size - 1]); return XCT_BROKEN; }