Commit 0fab1a6f authored by Lev Walkin's avatar Lev Walkin

relaxed XER processing rules for whitespace

parent 9a0f8fad
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.
......
......@@ -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;
}
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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;
......
......@@ -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
......
......@@ -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
......
......@@ -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.
*/
......
......@@ -16,6 +16,20 @@ asn_struct_free_f ASN__PRIMITIVE_TYPE_free;
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 */
......@@ -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) {
......
......@@ -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.
......
......@@ -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;
}
......@@ -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_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment