aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2005-03-09 22:19:25 +0000
committerLev Walkin <vlm@lionet.info>2005-03-09 22:19:25 +0000
commit0fab1a6fedfed87f5ebf182c771a4ce7269f4e9c (patch)
tree2a397ddc9a85ec53409b25bca0bb689bb6072128
parent9a0f8fad2f4d5ffb02d3fef8f6d3428755ee01a3 (diff)
relaxed XER processing rules for whitespace
-rw-r--r--ChangeLog14
-rw-r--r--skeletons/BOOLEAN.c23
-rw-r--r--skeletons/INTEGER.c24
-rw-r--r--skeletons/NULL.c10
-rw-r--r--skeletons/OBJECT_IDENTIFIER.c24
-rw-r--r--skeletons/OCTET_STRING.c50
-rw-r--r--skeletons/REAL.c25
-rw-r--r--skeletons/RELATIVE-OID.c23
-rw-r--r--skeletons/asn_codecs_prim.c64
-rw-r--r--skeletons/asn_codecs_prim.h19
-rw-r--r--skeletons/xer_decoder.c20
-rw-r--r--skeletons/xer_decoder.h10
-rw-r--r--skeletons/xer_support.c13
-rw-r--r--skeletons/xer_support.h4
14 files changed, 189 insertions, 134 deletions
diff --git a/ChangeLog b/ChangeLog
index f319db2a..43ffed75 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 &lt; 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_ */