diff options
author | Lev Walkin <vlm@lionet.info> | 2005-03-09 22:19:25 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2005-03-09 22:19:25 +0000 |
commit | 0fab1a6fedfed87f5ebf182c771a4ce7269f4e9c (patch) | |
tree | 2a397ddc9a85ec53409b25bca0bb689bb6072128 | |
parent | 9a0f8fad2f4d5ffb02d3fef8f6d3428755ee01a3 (diff) |
relaxed XER processing rules for whitespace
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | skeletons/BOOLEAN.c | 23 | ||||
-rw-r--r-- | skeletons/INTEGER.c | 24 | ||||
-rw-r--r-- | skeletons/NULL.c | 10 | ||||
-rw-r--r-- | skeletons/OBJECT_IDENTIFIER.c | 24 | ||||
-rw-r--r-- | skeletons/OCTET_STRING.c | 50 | ||||
-rw-r--r-- | skeletons/REAL.c | 25 | ||||
-rw-r--r-- | skeletons/RELATIVE-OID.c | 23 | ||||
-rw-r--r-- | skeletons/asn_codecs_prim.c | 64 | ||||
-rw-r--r-- | skeletons/asn_codecs_prim.h | 19 | ||||
-rw-r--r-- | skeletons/xer_decoder.c | 20 | ||||
-rw-r--r-- | skeletons/xer_decoder.h | 10 | ||||
-rw-r--r-- | skeletons/xer_support.c | 13 | ||||
-rw-r--r-- | skeletons/xer_support.h | 4 |
14 files changed, 189 insertions, 134 deletions
@@ -1,9 +1,15 @@ -0.9.12: 2005-Mar-05 +0.9.12: 2005-Mar-09 * Fixed a name clash in produced constraint checking code. * #includes are now in single quotes (to solve a name clash with system's <time.h> on a Win32 system). + * Small refinement of XML DTD generation (`asn1c -X`). + * Relaxed XER processing rules to skip extra whitespace + in some more places. It also skips XML comments (although + prohibited by X.693, #8.2.1). + (Test case 70) (Severity: medium, Security impact: none) + Reported by <Dominique.Nerriec@alcatel.fr>. 0.9.11: 2005-Mar-04 @@ -53,7 +59,7 @@ identifiers (./tests/68-*-OK.asn1). * ber_dec_rval_t renamed into asn_dec_rval_t: more generality. * Extensions in CHOICE types are properly marked as non-pointers - (Test case 59) (Severity: medium, Secruity impact: medium) + (Test case 59) (Severity: medium, Security impact: medium) Reported by <roman.pfender@sdm.de>. * Tagged CHOICE type is now supported again. (Test case 59) (Severity: low, Security impact: low) @@ -77,7 +83,7 @@ optionals-laden indefinite length structure. The code was previously refusing to parse such structures. * Fixed explicitly tagged ANY type encoding and decoding - (Severity: medium, Secruity impact: low). + (Severity: medium, Security impact: low). * Fixed CHOICE code spin when indefinite length structures appear in the extensions (Severity: medium, Security impact: medium). Reported by <siden@ul-gsm.ru>. @@ -95,7 +101,7 @@ * Added -fno-constraints option to asn1c, which disabled generation of ASN.1 subtype constraints checking code. * Added ASN1C_ENVIRONMENT_VERSION and get_asn1c_environment_version(). - * Fixed ANY type decoding (Severity: high, Secruity impact: low). + * Fixed ANY type decoding (Severity: high, Security impact: low). * Fixed BER decoder restartability problem with certain primitive types (BOOLEAN, INTEGER, and REAL). The problem occured when the encoding of such type is split between several bytes. diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c index ad7321ce..04e6560e 100644 --- a/skeletons/BOOLEAN.c +++ b/skeletons/BOOLEAN.c @@ -133,16 +133,14 @@ BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr, /* * Decode the chunk of XML text encoding INTEGER. */ -static ssize_t -BOOLEAN__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) { +static enum xer_pbd_rval +BOOLEAN__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) { BOOLEAN_t *st = (BOOLEAN_t *)sptr; - char *p = (char *)chunk_buf; + const char *p = (const char *)chunk_buf; (void)td; - if(chunk_size == 0) return -1; - - if(p[0] == 0x3c /* '<' */) { + if(chunk_size && p[0] == 0x3c /* '<' */) { switch(xer_check_tag(chunk_buf, chunk_size, "false")) { case XCT_BOTH: /* "<false/>" */ @@ -151,19 +149,20 @@ BOOLEAN__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, case XCT_UNKNOWN_BO: if(xer_check_tag(chunk_buf, chunk_size, "true") != XCT_BOTH) - return -1; + return XPBD_BROKEN_ENCODING; /* "<true/>" */ *st = 1; /* Or 0xff as in DER?.. */ break; default: - return -1; + return XPBD_BROKEN_ENCODING; } + return XPBD_BODY_CONSUMED; } else { - if(!xer_is_whitespace(chunk_buf, chunk_size)) - return -1; + if(xer_is_whitespace(chunk_buf, chunk_size)) + return XPBD_NOT_BODY_IGNORE; + else + return XPBD_BROKEN_ENCODING; } - - return chunk_size; } diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c index 246a02d5..a20bee11 100644 --- a/skeletons/INTEGER.c +++ b/skeletons/INTEGER.c @@ -299,8 +299,8 @@ INTEGER__map_value2enum(asn_INTEGER_specifics_t *specs, long value) { /* * Decode the chunk of XML text encoding INTEGER. */ -static ssize_t -INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) { +static enum xer_pbd_rval +INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) { INTEGER_t *st = (INTEGER_t *)sptr; long sign = 1; long value; @@ -345,7 +345,7 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, if(new_value / 10 != value) /* Overflow */ - return -1; + return XPBD_DECODER_LIMIT; value = new_value + (lv - 0x30); /* Check for two's complement overflow */ @@ -357,7 +357,7 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, sign = 1; } else { /* Overflow */ - return -1; + return XPBD_DECODER_LIMIT; } } } @@ -377,20 +377,26 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, } ASN_DEBUG("Unknown identifier for INTEGER"); } - return -1; + return XPBD_BROKEN_ENCODING; } break; } - if(state != ST_DIGITS) - return -1; /* No digits */ + if(state != ST_DIGITS) { + if(xer_is_whitespace(chunk_buf, chunk_size)) { + return XPBD_NOT_BODY_IGNORE; + } else { + ASN_DEBUG("No useful digits in output"); + return XPBD_BROKEN_ENCODING; /* No digits */ + } + } value *= sign; /* Change sign, if needed */ if(asn_long2INTEGER(st, value)) - return -1; + return XPBD_SYSTEM_FAILURE; - return lp - lstart; + return XPBD_BODY_CONSUMED; } asn_dec_rval_t diff --git a/skeletons/NULL.c b/skeletons/NULL.c index 6a813fcf..d5d98d9f 100644 --- a/skeletons/NULL.c +++ b/skeletons/NULL.c @@ -67,13 +67,15 @@ NULL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, } -static ssize_t -NULL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) { +static enum xer_pbd_rval +NULL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) { (void)td; (void)sptr; + if(xer_is_whitespace(chunk_buf, chunk_size)) - return chunk_size; - return -1; + return XPBD_BODY_CONSUMED; + else + return XPBD_BROKEN_ENCODING; } asn_dec_rval_t diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c index 4128e765..eeb9e5f2 100644 --- a/skeletons/OBJECT_IDENTIFIER.c +++ b/skeletons/OBJECT_IDENTIFIER.c @@ -263,8 +263,8 @@ OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st, asn_app_consume_byte return wrote_len; } -static ssize_t -OBJECT_IDENTIFIER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) { +static enum xer_pbd_rval +OBJECT_IDENTIFIER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) { OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr; char *endptr; long s_arcs[10]; @@ -275,27 +275,31 @@ OBJECT_IDENTIFIER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void * (void)td; arcs_count = OBJECT_IDENTIFIER_parse_arcs( - (const char *)chunk_buf, chunk_size, arcs, 10, &endptr); - if(arcs_count <= 0) - return -1; /* Expecting more than zero arcs */ - if(arcs_count > 10) { + (const char *)chunk_buf, chunk_size, arcs, + sizeof(s_arcs)/sizeof(s_arcs[0]), &endptr); + if(arcs_count <= 0) { + /* Expecting more than zero arcs */ + return XPBD_BROKEN_ENCODING; + } + + if((size_t)arcs_count > sizeof(s_arcs)/sizeof(s_arcs[0])) { arcs = (long *)MALLOC(arcs_count * sizeof(long)); - if(!arcs) return -1; + if(!arcs) return XPBD_SYSTEM_FAILURE; ret = OBJECT_IDENTIFIER_parse_arcs( (const char *)chunk_buf, chunk_size, arcs, arcs_count, &endptr); if(ret != arcs_count) - return -1; /* assert?.. */ + return XPBD_SYSTEM_FAILURE; /* assert?.. */ } /* * Convert arcs into BER representation. */ ret = OBJECT_IDENTIFIER_set_arcs(st, arcs, sizeof(*arcs), arcs_count); - if(ret) return -1; + if(ret) return XPBD_BROKEN_ENCODING; if(arcs != s_arcs) FREEMEM(arcs); - return endptr - (char *)chunk_buf; + return XPBD_BODY_CONSUMED; } asn_dec_rval_t diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c index a020339d..26df4bc9 100644 --- a/skeletons/OCTET_STRING.c +++ b/skeletons/OCTET_STRING.c @@ -691,7 +691,7 @@ static struct OCTET_STRING__xer_escape_table_s { }; static int -OS__check_escaped_control_char(void *buf, int size) { +OS__check_escaped_control_char(const void *buf, int size) { size_t i; /* * Inefficient algorithm which translates the escape sequences @@ -709,7 +709,7 @@ OS__check_escaped_control_char(void *buf, int size) { } static int -OCTET_STRING__handle_control_chars(void *struct_ptr, void *chunk_buf, size_t chunk_size) { +OCTET_STRING__handle_control_chars(void *struct_ptr, const void *chunk_buf, size_t chunk_size) { /* * This might be one of the escape sequences * for control characters. Check it out. @@ -778,11 +778,11 @@ OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *sptr, /* * Convert from hexadecimal format (cstring): "AB CD EF" */ -static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, void *chunk_buf, size_t chunk_size, int have_more) { +static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) { OCTET_STRING_t *st = (OCTET_STRING_t *)sptr; - char *chunk_stop = (char *)chunk_buf; - char *p = chunk_stop; - char *pend = p + chunk_size; + const char *chunk_stop = (const char *)chunk_buf; + const char *p = chunk_stop; + const char *pend = p + chunk_size; unsigned int clv = 0; int half = 0; /* Half bit */ uint8_t *buf; @@ -800,7 +800,7 @@ static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, void *chunk_buf, si * than chunk_size, then it'll be equivalent to "ABC0". */ for(; p < pend; p++) { - int ch = *(unsigned char *)p; + int ch = *(const unsigned char *)p; switch(ch) { case 0x09: case 0x0a: case 0x0c: case 0x0d: case 0x20: @@ -849,16 +849,16 @@ static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, void *chunk_buf, si assert(st->size <= _ns); st->buf[st->size] = 0; /* Courtesy termination */ - return (chunk_stop - (char *)chunk_buf); /* Converted size */ + return (chunk_stop - (const char *)chunk_buf); /* Converted size */ } /* * Convert from binary format: "00101011101" */ -static ssize_t OCTET_STRING__convert_binary(void *sptr, void *chunk_buf, size_t chunk_size, int have_more) { +static ssize_t OCTET_STRING__convert_binary(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) { BIT_STRING_t *st = (BIT_STRING_t *)sptr; - char *p = (char *)chunk_buf; - char *pend = p + chunk_size; + const char *p = (const char *)chunk_buf; + const char *pend = p + chunk_size; int bits_unused = st->bits_unused & 0x7; uint8_t *buf; @@ -880,7 +880,7 @@ static ssize_t OCTET_STRING__convert_binary(void *sptr, void *chunk_buf, size_t * Convert series of 0 and 1 into the octet string. */ for(; p < pend; p++) { - int ch = *(unsigned char *)p; + int ch = *(const unsigned char *)p; switch(ch) { case 0x09: case 0x0a: case 0x0c: case 0x0d: case 0x20: @@ -918,9 +918,9 @@ static ssize_t OCTET_STRING__convert_binary(void *sptr, void *chunk_buf, size_t * Something like strtod(), but with stricter rules. */ static int -OS__strtoent(int base, char *buf, char *end, int32_t *return_value) { +OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) { int32_t val = 0; - char *p; + const char *p; for(p = buf; p < end; p++) { int ch = *p; @@ -939,7 +939,7 @@ OS__strtoent(int base, char *buf, char *end, int32_t *return_value) { val = val * base + (ch - 0x61 + 10); break; case 0x3b: /* ';' */ - *return_value = val; + *ret_value = val; return (p - buf) + 1; default: return -1; /* Character set error */ @@ -953,10 +953,10 @@ OS__strtoent(int base, char *buf, char *end, int32_t *return_value) { /* * Convert from the plain UTF-8 format, expanding entity references: "2 < 3" */ -static ssize_t OCTET_STRING__convert_entrefs(void *sptr, void *chunk_buf, size_t chunk_size, int have_more) { +static ssize_t OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) { OCTET_STRING_t *st = (OCTET_STRING_t *)sptr; - char *p = (char *)chunk_buf; - char *pend = p + chunk_size; + const char *p = (const char *)chunk_buf; + const char *pend = p + chunk_size; uint8_t *buf; /* Reallocate buffer */ @@ -970,7 +970,7 @@ static ssize_t OCTET_STRING__convert_entrefs(void *sptr, void *chunk_buf, size_t * Convert series of 0 and 1 into the octet string. */ for(; p < pend; p++) { - int ch = *(unsigned char *)p; + int ch = *(const unsigned char *)p; int len; /* Length of the rest of the chunk */ if(ch != 0x26 /* '&' */) { @@ -981,11 +981,11 @@ static ssize_t OCTET_STRING__convert_entrefs(void *sptr, void *chunk_buf, size_t /* * Process entity reference. */ - len = chunk_size - (p - (char *)chunk_buf); + len = chunk_size - (p - (const char *)chunk_buf); if(len == 1 /* "&" */) goto want_more; if(p[1] == 0x23 /* '#' */) { - char *pval; /* Pointer to start of digits */ - int32_t val; /* Entity reference value */ + const char *pval; /* Pointer to start of digits */ + int32_t val; /* Entity reference value */ int base; if(len == 2 /* "&#" */) goto want_more; @@ -1078,7 +1078,7 @@ static ssize_t OCTET_STRING__convert_entrefs(void *sptr, void *chunk_buf, size_t *buf++ = ch; continue; } - chunk_size = (p - (char *)chunk_buf); + chunk_size = (p - (const char *)chunk_buf); /* Processing stalled: need more data */ break; } @@ -1098,9 +1098,9 @@ OCTET_STRING__decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname, void *buf_ptr, size_t size, int (*opt_unexpected_tag_decoder) - (void *struct_ptr, void *chunk_buf, size_t chunk_size), + (void *struct_ptr, const void *chunk_buf, size_t chunk_size), ssize_t (*body_receiver) - (void *struct_ptr, void *chunk_buf, size_t chunk_size, + (void *struct_ptr, const void *chunk_buf, size_t chunk_size, int have_more) ) { OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr; diff --git a/skeletons/REAL.c b/skeletons/REAL.c index 717db899..4b73f4b7 100644 --- a/skeletons/REAL.c +++ b/skeletons/REAL.c @@ -257,17 +257,17 @@ REAL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, /* * Decode the chunk of XML text encoding REAL. */ -static ssize_t -REAL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) { +static enum xer_pbd_rval +REAL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) { REAL_t *st = (REAL_t *)sptr; double value; - char *xerdata = (char *)chunk_buf; + const char *xerdata = (const char *)chunk_buf; char *endptr = 0; char *b; (void)td; - if(!chunk_size) return -1; + if(!chunk_size) return XPBD_BROKEN_ENCODING; /* * Decode an XMLSpecialRealValue: <MINUS-INFINITY>, etc. @@ -292,33 +292,34 @@ REAL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, si case -1: dv = - INFINITY; break; case 0: dv = NAN; break; case 1: dv = INFINITY; break; - default: return -1; + default: return XPBD_SYSTEM_FAILURE; } - if(asn_double2REAL(st, dv)) return -1; + if(asn_double2REAL(st, dv)) + return XPBD_SYSTEM_FAILURE; - return chunk_size; + return XPBD_BODY_CONSUMED; } ASN_DEBUG("Unknown XMLSpecialRealValue"); - return -1; + return XPBD_BROKEN_ENCODING; } /* * Copy chunk into the nul-terminated string, and run strtod. */ b = (char *)MALLOC(chunk_size + 1); - if(!b) return -1; + if(!b) return XPBD_SYSTEM_FAILURE; memcpy(b, chunk_buf, chunk_size); b[chunk_size] = 0; /* nul-terminate */ value = strtod(b, &endptr); free(b); - if(endptr == b) return -1; + if(endptr == b) return XPBD_BROKEN_ENCODING; if(asn_double2REAL(st, value)) - return -1; + return XPBD_SYSTEM_FAILURE; - return endptr - b; + return XPBD_BODY_CONSUMED; } asn_dec_rval_t diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c index 70291e24..6a064d03 100644 --- a/skeletons/RELATIVE-OID.c +++ b/skeletons/RELATIVE-OID.c @@ -86,8 +86,8 @@ RELATIVE_OID_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, return (cb(" }", 2, app_key) < 0) ? -1 : 0; } -static ssize_t -RELATIVE_OID__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk_buf, size_t chunk_size) { +static enum xer_pbd_rval +RELATIVE_OID__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) { RELATIVE_OID_t *st = (RELATIVE_OID_t *)sptr; char *endptr; long s_arcs[6]; @@ -99,27 +99,30 @@ RELATIVE_OID__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, void *chunk arcs_count = OBJECT_IDENTIFIER_parse_arcs( (const char *)chunk_buf, chunk_size, - arcs, 6, &endptr); - if(arcs_count < 0) - return -1; /* Expecting at least zero arcs */ - if(arcs_count > 6) { + arcs, sizeof(s_arcs)/sizeof(s_arcs[0]), &endptr); + if(arcs_count < 0) { + /* Expecting at least zero arcs */ + return XPBD_BROKEN_ENCODING; + } + + if((size_t)arcs_count > sizeof(s_arcs)/sizeof(s_arcs[0])) { arcs = (long *)MALLOC(arcs_count * sizeof(long)); - if(!arcs) return -1; + if(!arcs) return XPBD_SYSTEM_FAILURE; ret = OBJECT_IDENTIFIER_parse_arcs( (const char *)chunk_buf, chunk_size, arcs, arcs_count, &endptr); if(ret != arcs_count) - return -1; /* assert?.. */ + return XPBD_SYSTEM_FAILURE; /* assert?.. */ } /* * Convert arcs into BER representation. */ ret = RELATIVE_OID_set_arcs(st, arcs, sizeof(*arcs), arcs_count); - if(ret) return -1; + if(ret) return XPBD_BROKEN_ENCODING; if(arcs != s_arcs) FREEMEM(arcs); - return endptr - (char *)chunk_buf; + return XPBD_BODY_CONSUMED; } asn_dec_rval_t diff --git a/skeletons/asn_codecs_prim.c b/skeletons/asn_codecs_prim.c index 42f5a40f..a2aeeee5 100644 --- a/skeletons/asn_codecs_prim.c +++ b/skeletons/asn_codecs_prim.c @@ -148,17 +148,16 @@ ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr, struct xdp_arg_s { asn_TYPE_descriptor_t *type_descriptor; void *struct_key; - ssize_t (*prim_body_decode)(asn_TYPE_descriptor_t *td, - void *struct_key, void *chunk_buf, size_t chunk_size); + xer_primitive_body_decoder_f *prim_body_decoder; int decoded_something; int want_more; }; -static ssize_t -xer_decode__unexpected_tag(void *key, void *chunk_buf, size_t chunk_size) { +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; - ssize_t decoded; + enum xer_pbd_rval bret; if(arg->decoded_something) { if(xer_is_whitespace(chunk_buf, chunk_size)) @@ -169,21 +168,28 @@ xer_decode__unexpected_tag(void *key, void *chunk_buf, size_t chunk_size) { return -1; } - decoded = arg->prim_body_decode(arg->type_descriptor, + bret = arg->prim_body_decoder(arg->type_descriptor, arg->struct_key, chunk_buf, chunk_size); - if(decoded < 0) { - return -1; - } else { + switch(bret) { + case XPBD_SYSTEM_FAILURE: + case XPBD_DECODER_LIMIT: + case XPBD_BROKEN_ENCODING: + break; + case XPBD_BODY_CONSUMED: /* Tag decoded successfully */ arg->decoded_something = 1; + /* Fall through */ + case XPBD_NOT_BODY_IGNORE: /* Safe to proceed further */ return 0; } + + return -1; } static ssize_t -xer_decode__body(void *key, void *chunk_buf, size_t chunk_size, int have_more) { +xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) { struct xdp_arg_s *arg = (struct xdp_arg_s *)key; - ssize_t decoded; + enum xer_pbd_rval bret; if(arg->decoded_something) { if(xer_is_whitespace(chunk_buf, chunk_size)) @@ -207,14 +213,22 @@ xer_decode__body(void *key, void *chunk_buf, size_t chunk_size, int have_more) { return -1; } - decoded = arg->prim_body_decode(arg->type_descriptor, + bret = arg->prim_body_decoder(arg->type_descriptor, arg->struct_key, chunk_buf, chunk_size); - if(decoded < 0) { - return -1; - } else { + switch(bret) { + case XPBD_SYSTEM_FAILURE: + case XPBD_DECODER_LIMIT: + case XPBD_BROKEN_ENCODING: + break; + case XPBD_BODY_CONSUMED: + /* Tag decoded successfully */ arg->decoded_something = 1; - return decoded; + /* Fall through */ + case XPBD_NOT_BODY_IGNORE: /* Safe to proceed further */ + return chunk_size; } + + return -1; } @@ -225,8 +239,7 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, size_t struct_size, const char *opt_mname, void *buf_ptr, size_t size, - ssize_t (*prim_body_decode)(asn_TYPE_descriptor_t *td, - void *struct_key, void *chunk_buf, size_t chunk_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; @@ -249,7 +262,7 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, memset(&s_ctx, 0, sizeof(s_ctx)); s_arg.type_descriptor = td; s_arg.struct_key = *sptr; - s_arg.prim_body_decode = prim_body_decode; + s_arg.prim_body_decoder = prim_body_decoder; s_arg.decoded_something = 0; s_arg.want_more = 0; @@ -260,9 +273,16 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, case RC_OK: if(!s_arg.decoded_something) { char ch; - /* Opportunity has come and gone. Where's the result? */ - if(prim_body_decode(s_arg.type_descriptor, - s_arg.struct_key, &ch, 0) != 0) { + ASN_DEBUG("Primitive body is not recognized, " + "supplying empty one"); + /* + * Decoding opportunity has come and gone. + * Where's the result? + * Try to feed with empty body, see if it eats it. + */ + if(prim_body_decoder(s_arg.type_descriptor, + s_arg.struct_key, &ch, 0) + != XPBD_BODY_CONSUMED) { /* * This decoder does not like empty stuff. */ diff --git a/skeletons/asn_codecs_prim.h b/skeletons/asn_codecs_prim.h index 7a6723d3..ceadf511 100644 --- a/skeletons/asn_codecs_prim.h +++ b/skeletons/asn_codecs_prim.h @@ -17,6 +17,20 @@ ber_type_decoder_f ber_decode_primitive; der_type_encoder_f der_encode_primitive; /* + * A callback specification for the xer_decode_primitive() function below. + */ +enum xer_pbd_rval { + XPBD_SYSTEM_FAILURE, /* System failure (memory shortage, etc) */ + XPBD_DECODER_LIMIT, /* Hit some decoder limitation or deficiency */ + XPBD_BROKEN_ENCODING, /* Encoding of a primitive body is broken */ + XPBD_NOT_BODY_IGNORE, /* Not a body format, but safe to ignore */ + XPBD_BODY_CONSUMED, /* Body is recognized and consumed */ +}; +typedef enum xer_pbd_rval (xer_primitive_body_decoder_f) + (asn_TYPE_descriptor_t *td, void *struct_ptr, + const void *chunk_buf, size_t chunk_size); + +/* * Specific function to decode simple primitive types. * Also see xer_decode_general() in xer_decoder.h */ @@ -25,8 +39,7 @@ asn_dec_rval_t xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx, void **struct_ptr, size_t struct_size, const char *opt_mname, void *buf_ptr, size_t size, - ssize_t (*prim_body_decode)(asn_TYPE_descriptor_t *td, - void *struct_ptr, void *chunk_buf, size_t chunk_size) - ); + xer_primitive_body_decoder_f *prim_body_decoder +); #endif /* ASN_CODECS_PRIM_H */ diff --git a/skeletons/xer_decoder.c b/skeletons/xer_decoder.c index 07a1936e..64566668 100644 --- a/skeletons/xer_decoder.c +++ b/skeletons/xer_decoder.c @@ -33,12 +33,12 @@ xer_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, struct xer__cb_arg { pxml_chunk_type_e chunk_type; size_t chunk_size; - void *chunk_buf; + const void *chunk_buf; int callback_not_invoked; }; static int -xer__token_cb(pxml_chunk_type_e type, void *_chunk_data, size_t _chunk_size, void *key) { +xer__token_cb(pxml_chunk_type_e type, const void *_chunk_data, size_t _chunk_size, void *key) { struct xer__cb_arg *arg = (struct xer__cb_arg *)key; arg->chunk_type = type; arg->chunk_size = _chunk_size; @@ -51,7 +51,7 @@ xer__token_cb(pxml_chunk_type_e type, void *_chunk_data, size_t _chunk_size, voi * Fetch the next token from the XER/XML stream. */ ssize_t -xer_next_token(int *stateContext, void *buffer, size_t size, pxer_chunk_type_e *ch_type) { +xer_next_token(int *stateContext, const void *buffer, size_t size, pxer_chunk_type_e *ch_type) { struct xer__cb_arg arg; int new_stateContext = *stateContext; ssize_t ret; @@ -151,7 +151,7 @@ xer_check_tag(const void *buf_ptr, int size, const char *need_tag) { #undef ADVANCE #define ADVANCE(num_bytes) do { \ size_t num = (num_bytes); \ - buf_ptr = ((char *)buf_ptr) + num; \ + buf_ptr = ((const char *)buf_ptr) + num; \ size -= num; \ consumed_myself += num; \ } while(0) @@ -186,11 +186,11 @@ xer_decode_general(asn_codec_ctx_t *opt_codec_ctx, asn_struct_ctx_t *ctx, /* Type decoder context */ void *struct_key, const char *xml_tag, /* Expected XML tag */ - void *buf_ptr, size_t size, + const void *buf_ptr, size_t size, int (*opt_unexpected_tag_decoder) - (void *struct_key, void *chunk_buf, size_t chunk_size), + (void *struct_key, const void *chunk_buf, size_t chunk_size), ssize_t (*body_receiver) - (void *struct_key, void *chunk_buf, size_t chunk_size, + (void *struct_key, const void *chunk_buf, size_t chunk_size, int have_more) ) { @@ -301,9 +301,9 @@ xer_decode_general(asn_codec_ctx_t *opt_codec_ctx, int -xer_is_whitespace(void *chunk_buf, size_t chunk_size) { - char *p = (char *)chunk_buf; - char *pend = p + chunk_size; +xer_is_whitespace(const void *chunk_buf, size_t chunk_size) { + const char *p = (const char *)chunk_buf; + const char *pend = p + chunk_size; for(; p < pend; p++) { switch(*p) { diff --git a/skeletons/xer_decoder.h b/skeletons/xer_decoder.h index fa8c3c69..4f6b537c 100644 --- a/skeletons/xer_decoder.h +++ b/skeletons/xer_decoder.h @@ -43,11 +43,11 @@ asn_dec_rval_t xer_decode_general(asn_codec_ctx_t *opt_codec_ctx, asn_struct_ctx_t *ctx, /* Type decoder context */ void *struct_key, /* Treated as opaque pointer */ const char *xml_tag, /* Expected XML tag name */ - void *buf_ptr, size_t size, + const void *buf_ptr, size_t size, int (*opt_unexpected_tag_decoder) - (void *struct_key, void *chunk_buf, size_t chunk_size), + (void *struct_key, const void *chunk_buf, size_t chunk_size), ssize_t (*body_receiver) - (void *struct_key, void *chunk_buf, size_t chunk_size, + (void *struct_key, const void *chunk_buf, size_t chunk_size, int have_more) ); @@ -64,7 +64,7 @@ asn_dec_rval_t xer_decode_general(asn_codec_ctx_t *opt_codec_ctx, PXER_COMMENT, /* A comment, may be part of */ } pxer_chunk_type_e; ssize_t xer_next_token(int *stateContext, - void *buffer, size_t size, pxer_chunk_type_e *_ch_type); + const void *buffer, size_t size, pxer_chunk_type_e *_ch_type); /* * This function checks the buffer against the tag name is expected to occur. @@ -88,7 +88,7 @@ xer_check_tag_e xer_check_tag(const void *buf_ptr, int size, * 1: Whitespace or empty string * 0: Non-whitespace */ -int xer_is_whitespace(void *chunk_buf, size_t chunk_size); +int xer_is_whitespace(const void *chunk_buf, size_t chunk_size); /* * Skip the series of anticipated extensions. diff --git a/skeletons/xer_support.c b/skeletons/xer_support.c index b2f542cd..21c92b09 100644 --- a/skeletons/xer_support.c +++ b/skeletons/xer_support.c @@ -58,6 +58,7 @@ _charclass[256] = { #define LANGLE 0x3c /* '<' */ #define CEQUAL 0x3d /* '=' */ #define RANGLE 0x3e /* '>' */ +#define CQUEST 0x3f /* '?' */ /* Invoke token callback */ #define TOKEN_CB_CALL(type, _ns, _current_too, _final) do { \ @@ -88,14 +89,14 @@ _charclass[256] = { /* * Parser itself */ -ssize_t pxml_parse(int *stateContext, void *xmlbuf, size_t size, pxml_callback_f *cb, void *key) { +ssize_t pxml_parse(int *stateContext, const void *xmlbuf, size_t size, pxml_callback_f *cb, void *key) { pstate_e state = (pstate_e)*stateContext; - char *chunk_start = (char *)xmlbuf; - char *p = chunk_start; - char *end = p + size; + const char *chunk_start = (const char *)xmlbuf; + const char *p = chunk_start; + const char *end = p + size; for(; p < end; p++) { - int C = *(unsigned char *)p; + int C = *(const unsigned char *)p; switch(state) { case ST_TEXT: /* @@ -229,6 +230,6 @@ ssize_t pxml_parse(int *stateContext, void *xmlbuf, size_t size, pxml_callback_f finish: *stateContext = (int)state; - return chunk_start - (char *)xmlbuf; + return chunk_start - (const char *)xmlbuf; } diff --git a/skeletons/xer_support.h b/skeletons/xer_support.h index 2fa1ae96..e25678c0 100644 --- a/skeletons/xer_support.h +++ b/skeletons/xer_support.h @@ -32,7 +32,7 @@ typedef enum { * The chunk is NOT '\0'-terminated. */ typedef int (pxml_callback_f)(pxml_chunk_type_e _type, - void *_chunk_data, size_t _chunk_size, void *_key); + const void *_chunk_data, size_t _chunk_size, void *_key); /* * Parse the given buffer as it were a chunk of XML data. @@ -41,7 +41,7 @@ typedef int (pxml_callback_f)(pxml_chunk_type_e _type, * It will always be lesser than or equal to the specified _size. * The next invocation of this function must account the difference. */ -ssize_t pxml_parse(int *_stateContext, void *_buf, size_t _size, +ssize_t pxml_parse(int *_stateContext, const void *_buf, size_t _size, pxml_callback_f *cb, void *_key); #endif /* _XER_SUPPORT_H_ */ |