X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/46b0747592074017ff0ea4b33d4a7194235886e5..0c097ef3435d2a45c1ee4ac80f8bd3f254fb8df5:/libs/smux/asn_codecs_prim.c?ds=sidebyside diff --git a/libs/smux/asn_codecs_prim.c b/libs/smux/asn_codecs_prim.c index 4e5c6393..78448a8e 100644 --- a/libs/smux/asn_codecs_prim.c +++ b/libs/smux/asn_codecs_prim.c @@ -10,19 +10,19 @@ * Decode an always-primitive type. */ asn_dec_rval_t -ber_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, - void **sptr, const void *buf_ptr, size_t size, int tag_mode) { - ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr; +ber_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, + const void *buf_ptr, size_t size, int tag_mode) { + ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr; asn_dec_rval_t rval; - ber_tlv_len_t length; + ber_tlv_len_t length = 0; /* =0 to avoid [incorrect] warning. */ /* * If the structure is not there, allocate it. */ if(st == NULL) { st = (ASN__PRIMITIVE_TYPE_t *)CALLOC(1, sizeof(*st)); - if(st == NULL) _ASN_DECODE_FAILED; + if(st == NULL) ASN__DECODE_FAILED; *sptr = (void *)st; } @@ -55,13 +55,13 @@ ber_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, if(sizeof(st->size) != sizeof(length) && (ber_tlv_len_t)st->size != length) { st->size = 0; - _ASN_DECODE_FAILED; + ASN__DECODE_FAILED; } st->buf = (uint8_t *)MALLOC(length + 1); if(!st->buf) { st->size = 0; - _ASN_DECODE_FAILED; + ASN__DECODE_FAILED; } memcpy(st->buf, buf_ptr, length); @@ -81,11 +81,11 @@ ber_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, * Encode an always-primitive type using DER. */ asn_enc_rval_t -der_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr, - int tag_mode, ber_tlv_tag_t tag, - asn_app_consume_bytes_f *cb, void *app_key) { - asn_enc_rval_t erval; - ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr; +der_encode_primitive(const asn_TYPE_descriptor_t *td, const void *sptr, + int tag_mode, ber_tlv_tag_t tag, + asn_app_consume_bytes_f *cb, void *app_key) { + asn_enc_rval_t erval; + const ASN__PRIMITIVE_TYPE_t *st = (const ASN__PRIMITIVE_TYPE_t *)sptr; ASN_DEBUG("%s %s as a primitive type (tm=%d)", cb?"Encoding":"Estimating", td->name, tag_mode); @@ -111,13 +111,13 @@ der_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr, } erval.encoded += st->size; - _ASN_ENCODED_OK(erval); + ASN__ENCODED_OK(erval); } void -ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr, - int contents_only) { - ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr; +ASN__PRIMITIVE_TYPE_free(const asn_TYPE_descriptor_t *td, void *sptr, + enum asn_struct_free_method method) { + ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr; if(!td || !sptr) return; @@ -127,8 +127,16 @@ ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr, if(st->buf) FREEMEM(st->buf); - if(!contents_only) - FREEMEM(st); + switch(method) { + case ASFM_FREE_EVERYTHING: + FREEMEM(sptr); + break; + case ASFM_FREE_UNDERLYING: + break; + case ASFM_FREE_UNDERLYING_AND_RESET: + memset(sptr, 0, sizeof(ASN__PRIMITIVE_TYPE_t)); + break; + } } @@ -136,27 +144,33 @@ ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr, * Local internal type passed around as an argument. */ struct xdp_arg_s { - asn_TYPE_descriptor_t *type_descriptor; - void *struct_key; + const asn_TYPE_descriptor_t *type_descriptor; + void *struct_key; xer_primitive_body_decoder_f *prim_body_decoder; int decoded_something; int want_more; }; - +/* + * Since some kinds of primitive values can be encoded using value-specific + * tags (, , etc), the primitive decoder must + * be supplied with such tags to parse them as needed. + */ static int xer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size) { struct xdp_arg_s *arg = (struct xdp_arg_s *)key; enum xer_pbd_rval bret; - if(arg->decoded_something) { - if(xer_is_whitespace(chunk_buf, chunk_size)) - return 0; /* Skip it. */ - /* - * Decoding was done once already. Prohibit doing it again. - */ + /* + * The chunk_buf is guaranteed to start at '<'. + */ + assert(chunk_size && ((const char *)chunk_buf)[0] == 0x3c); + + /* + * Decoding was performed once already. Prohibit doing it again. + */ + if(arg->decoded_something) return -1; - } bret = arg->prim_body_decoder(arg->type_descriptor, arg->struct_key, chunk_buf, chunk_size); @@ -177,13 +191,20 @@ xer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size) } static ssize_t -xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) { +xer_decode__primitive_body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) { struct xdp_arg_s *arg = (struct xdp_arg_s *)key; enum xer_pbd_rval bret; + size_t lead_wsp_size; if(arg->decoded_something) { - if(xer_is_whitespace(chunk_buf, chunk_size)) + if(xer_whitespace_span(chunk_buf, chunk_size) == chunk_size) { + /* + * Example: + * "123 " + * ^- chunk_buf position. + */ return chunk_size; + } /* * Decoding was done once already. Prohibit doing it again. */ @@ -203,6 +224,10 @@ xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_m return -1; } + lead_wsp_size = xer_whitespace_span(chunk_buf, chunk_size); + chunk_buf = (const char *)chunk_buf + lead_wsp_size; + chunk_size -= lead_wsp_size; + bret = arg->prim_body_decoder(arg->type_descriptor, arg->struct_key, chunk_buf, chunk_size); switch(bret) { @@ -215,7 +240,7 @@ xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_m arg->decoded_something = 1; /* Fall through */ case XPBD_NOT_BODY_IGNORE: /* Safe to proceed further */ - return chunk_size; + return lead_wsp_size + chunk_size; } return -1; @@ -223,15 +248,12 @@ xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_m asn_dec_rval_t -xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, - asn_TYPE_descriptor_t *td, - void **sptr, - size_t struct_size, - const char *opt_mname, - const void *buf_ptr, size_t size, - xer_primitive_body_decoder_f *prim_body_decoder -) { - const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; +xer_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx, + const asn_TYPE_descriptor_t *td, void **sptr, + size_t struct_size, const char *opt_mname, + const void *buf_ptr, size_t size, + xer_primitive_body_decoder_f *prim_body_decoder) { + const char *xml_tag = opt_mname ? opt_mname : td->xml_tag; asn_struct_ctx_t s_ctx; struct xdp_arg_s s_arg; asn_dec_rval_t rc; @@ -241,7 +263,7 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, */ if(!*sptr) { *sptr = CALLOC(1, struct_size); - if(!*sptr) _ASN_DECODE_FAILED; + if(!*sptr) ASN__DECODE_FAILED; } memset(&s_ctx, 0, sizeof(s_ctx)); @@ -253,7 +275,7 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, rc = xer_decode_general(opt_codec_ctx, &s_ctx, &s_arg, xml_tag, buf_ptr, size, - xer_decode__unexpected_tag, xer_decode__body); + xer_decode__unexpected_tag, xer_decode__primitive_body); switch(rc.code) { case RC_OK: if(!s_arg.decoded_something) { @@ -271,7 +293,7 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, /* * This decoder does not like empty stuff. */ - _ASN_DECODE_FAILED; + ASN__DECODE_FAILED; } } break; @@ -287,7 +309,7 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, if(s_arg.want_more) rc.code = RC_WMORE; else - _ASN_DECODE_FAILED; + ASN__DECODE_FAILED; break; } return rc;