aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2004-10-21 12:11:57 +0000
committerLev Walkin <vlm@lionet.info>2004-10-21 12:11:57 +0000
commit0be3a99877a563387b6384cdc5272d1040517901 (patch)
treeed675ab95b274c6a40820b807289a356a288d2e8
parent2ffc01d3e696d80c57ee0819a7d1ba9d8cd961f6 (diff)
INTEGER XER decoding
-rw-r--r--skeletons/INTEGER.c21
-rw-r--r--skeletons/asn_codecs_prim.c28
-rw-r--r--skeletons/tests/check-INTEGER.c63
3 files changed, 107 insertions, 5 deletions
diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c
index c4fb9721..1037bdd4 100644
--- a/skeletons/INTEGER.c
+++ b/skeletons/INTEGER.c
@@ -183,6 +183,7 @@ static ssize_t
INTEGER__xer_body_decode(INTEGER_t *st, void *chunk_buf, size_t chunk_size) {
long sign = 1;
long value;
+ char *lp;
char *lstart = (char *)chunk_buf;
char *lstop = chunk_buf + chunk_size;
enum {
@@ -190,12 +191,13 @@ INTEGER__xer_body_decode(INTEGER_t *st, void *chunk_buf, size_t chunk_size) {
ST_WAITDIGITS,
ST_DIGITS,
} state = ST_SKIPSPACE;
+
/*
* We may receive a tag here. But we aren't ready to deal with it yet.
* So, just use stroul()-like code and serialize the result.
*/
- for(value = 0; lstart < lstop; lstart++) {
- int lv = *lstart;
+ for(value = 0, lp = lstart; lp < lstop; lp++) {
+ int lv = *lp;
switch(lv) {
case 0x09: case 0x0a: case 0x0d: case 0x20:
if(state == ST_SKIPSPACE) continue;
@@ -217,20 +219,29 @@ INTEGER__xer_body_decode(INTEGER_t *st, void *chunk_buf, size_t chunk_size) {
case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
if(state != ST_DIGITS) state = ST_DIGITS;
- value = value * 10 + (lv - 0x30);
+ {
+ long new_value = value * 10;
+
+ if(new_value / 10 != value)
+ /* Overflow */
+ return -1;
+
+ value = new_value + (lv - 0x30);
/* Check for two's complement overflow */
if(value < 0) {
/* Check whether it is a LONG_MIN */
if(sign == -1
&& value == ~((unsigned long)-1 >> 1)) {
- sign = 0;
+ sign = 1;
} else {
/* Overflow */
return -1;
}
}
+ }
continue;
}
+ break;
}
if(state != ST_DIGITS)
@@ -241,7 +252,7 @@ INTEGER__xer_body_decode(INTEGER_t *st, void *chunk_buf, size_t chunk_size) {
if(asn_long2INTEGER(st, value))
return -1;
- return lstop - lstart;
+ return lp - lstart;
}
asn_dec_rval_t
diff --git a/skeletons/asn_codecs_prim.c b/skeletons/asn_codecs_prim.c
index e0b545a5..87914756 100644
--- a/skeletons/asn_codecs_prim.c
+++ b/skeletons/asn_codecs_prim.c
@@ -143,12 +143,38 @@ struct xdp_arg_s {
int want_more;
};
+/*
+ * Check whether this buffer consists of entirely XER whitespace characters.
+ */
+static int
+xer_decode__check_whitespace(void *chunk_buf, size_t chunk_size) {
+ char *p = (char *)chunk_buf;
+ char *pend = p + chunk_size;
+ for(; p < pend; p++) {
+ switch(*p) {
+ /* X.693, #8.1.4
+ * HORISONTAL TAB (9)
+ * LINE FEED (10)
+ * CARRIAGE RETURN (13)
+ * SPACE (32)
+ */
+ case 0x09: case 0x0a: case 0x0d: case 0x20:
+ break;
+ default:
+ return 0;
+ }
+ }
+ return 1; /* All whitespace */
+}
+
static int
xer_decode__unexpected_tag(void *key, void *chunk_buf, size_t chunk_size) {
struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
ssize_t decoded;
if(arg->decoded_something) {
+ if(xer_decode__check_whitespace(chunk_buf, chunk_size))
+ return chunk_size;
/*
* Decoding was done once already. Prohibit doing it again.
*/
@@ -171,6 +197,8 @@ xer_decode__body(void *key, void *chunk_buf, size_t chunk_size, int have_more) {
ssize_t decoded;
if(arg->decoded_something) {
+ if(xer_decode__check_whitespace(chunk_buf, chunk_size))
+ return chunk_size;
/*
* Decoding was done once already. Prohibit doing it again.
*/
diff --git a/skeletons/tests/check-INTEGER.c b/skeletons/tests/check-INTEGER.c
index ea686b43..81aae6e5 100644
--- a/skeletons/tests/check-INTEGER.c
+++ b/skeletons/tests/check-INTEGER.c
@@ -78,6 +78,34 @@ check(uint8_t *buf, int size, long check_long, int check_ret) {
}
}
+static void
+check_xer(int tofail, char *xmldata, long orig_value) {
+ INTEGER_t *st = 0;
+ asn_dec_rval_t rc;
+ long value;
+ int ret;
+
+ printf("[%s] vs %ld:\n", xmldata, orig_value);
+
+ rc = xer_decode(0, &asn_DEF_INTEGER, (void *)&st,
+ xmldata, strlen(xmldata));
+ if(rc.code != RC_OK) {
+ assert(tofail);
+ printf("\tfailed, as expected\n");
+ return;
+ }
+ assert(!tofail);
+
+ ret = asn_INTEGER2long(st, &value);
+ assert(ret == 0);
+
+ printf("\t%ld\n", value);
+
+ assert(value == orig_value);
+
+ asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, st, 0);
+}
+
int
main(int ac, char **av) {
uint8_t buf1[] = { 1 };
@@ -110,5 +138,40 @@ main(int ac, char **av) {
CHECK(buf12, -32768, 0);
CHECK(buf13, -128, 0);
+ check_xer(-1, "", 0);
+ check_xer(-1, "<INTEGER></INTEGER>", 0);
+ check_xer(-1, "<INTEGER>-</INTEGER>", 0);
+ check_xer(-1, "<INTEGER>+</INTEGER>", 0);
+ check_xer(-1, "<INTEGER>+-</INTEGER>", 0);
+ check_xer(0, "<INTEGER>+0</INTEGER>", 0);
+ check_xer(0, "<INTEGER>-0</INTEGER>", 0);
+ check_xer(0, "<INTEGER>+1</INTEGER>", 1);
+ check_xer(0, "<INTEGER>-1</INTEGER>", -1);
+ check_xer(0, "<INTEGER>1</INTEGER>", 1);
+ check_xer(0, "<INTEGER>-15</INTEGER>", -15);
+ check_xer(0, "<INTEGER>+15</INTEGER>", 15);
+ check_xer(0, "<INTEGER>15</INTEGER>", 15);
+ check_xer(0, "<INTEGER> 15</INTEGER>", 15);
+ check_xer(0, "<INTEGER> 15 </INTEGER>", 15);
+ check_xer(0, "<INTEGER>15 </INTEGER>", 15);
+ check_xer(0, "<INTEGER> +15 </INTEGER>", 15);
+ check_xer(-1, "<INTEGER> +15 -</INTEGER>", 0);
+ check_xer(-1, "<INTEGER> +15 1</INTEGER>", 0);
+ check_xer(-1, "<INTEGER>+ 15</INTEGER>", 0);
+ check_xer(-1, "<INTEGER>12<z>34</INTEGER>", 0);
+ check_xer(0, "<INTEGER>1234</INTEGER>", 1234);
+ check_xer(-1, "<INTEGER>1234 5678</INTEGER>", 0);
+ check_xer(0, "<INTEGER>-2147483647</INTEGER>", -2147483647);
+ check_xer(0, "<INTEGER>-2147483648</INTEGER>", -2147483648);
+ check_xer(0, "<INTEGER>+2147483647</INTEGER>", 2147483647);
+ check_xer(0, "<INTEGER>2147483647</INTEGER>", 2147483647);
+ check_xer(-1, "<INTEGER>2147483648</INTEGER>", 0);
+ check_xer(-1, "<INTEGER>2147483649</INTEGER>", 0);
+ check_xer(-1, "<INTEGER>3147483649</INTEGER>", 0);
+ check_xer(-1, "<INTEGER>4147483649</INTEGER>", 0);
+ check_xer(-1, "<INTEGER>5147483649</INTEGER>", 0); /* unobvious */
+ check_xer(-1, "<INTEGER>9147483649</INTEGER>", 0);
+ check_xer(-1, "<INTEGER>9999999999</INTEGER>", 0);
+
return 0;
}