summaryrefslogtreecommitdiff
path: root/qpid/extras/dispatch/src/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/extras/dispatch/src/parse.c')
-rw-r--r--qpid/extras/dispatch/src/parse.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/qpid/extras/dispatch/src/parse.c b/qpid/extras/dispatch/src/parse.c
index 3b47ad216a..c5ecc4e498 100644
--- a/qpid/extras/dispatch/src/parse.c
+++ b/qpid/extras/dispatch/src/parse.c
@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -37,13 +37,14 @@ ALLOC_DECLARE(dx_parsed_field_t);
ALLOC_DEFINE(dx_parsed_field_t);
-static char *get_type_info(dx_field_iterator_t *iter, uint8_t *tag, uint32_t *length, uint32_t *count)
+static char *get_type_info(dx_field_iterator_t *iter, uint8_t *tag, uint32_t *length, uint32_t *count, uint32_t *clen)
{
if (dx_field_iterator_end(iter))
return "Insufficient Data to Determine Tag";
- *tag = dx_field_iterator_octet(iter);
- *count = 0;
- *length = 0;
+ *tag = dx_field_iterator_octet(iter);
+ *count = 0;
+ *length = 0;
+ *clen = 0;
switch (*tag & 0xF0) {
case 0x40: *length = 0; break;
@@ -59,7 +60,7 @@ static char *get_type_info(dx_field_iterator_t *iter, uint8_t *tag, uint32_t *le
*length += ((unsigned int) dx_field_iterator_octet(iter)) << 16;
*length += ((unsigned int) dx_field_iterator_octet(iter)) << 8;
// fall through to the next case
-
+
case 0xA0:
case 0xC0:
case 0xE0:
@@ -78,19 +79,24 @@ static char *get_type_info(dx_field_iterator_t *iter, uint8_t *tag, uint32_t *le
*count += ((unsigned int) dx_field_iterator_octet(iter)) << 24;
*count += ((unsigned int) dx_field_iterator_octet(iter)) << 16;
*count += ((unsigned int) dx_field_iterator_octet(iter)) << 8;
+ *clen = 3;
// fall through to the next case
-
+
case 0xC0:
case 0xE0:
if (dx_field_iterator_end(iter))
return "Insufficient Data to Determine Count";
*count += (unsigned int) dx_field_iterator_octet(iter);
+ *clen += 1;
break;
}
if ((*tag == DX_AMQP_MAP8 || *tag == DX_AMQP_MAP32) && (*count & 1))
return "Odd Number of Elements in a Map";
+ if (*clen > *length)
+ return "Insufficient Length to Determine Count";
+
return 0;
}
@@ -108,13 +114,13 @@ static dx_parsed_field_t *dx_parse_internal(dx_field_iterator_t *iter, dx_parsed
uint32_t length;
uint32_t count;
+ uint32_t length_of_count;
- field->parse_error = get_type_info(iter, &field->tag, &length, &count);
+ field->parse_error = get_type_info(iter, &field->tag, &length, &count, &length_of_count);
if (!field->parse_error) {
field->raw_iter = dx_field_iterator_sub(iter, length);
- if (count == 0 && length > 0)
- dx_field_iterator_advance(iter, length);
+ dx_field_iterator_advance(iter, length - length_of_count);
for (uint32_t idx = 0; idx < count; idx++) {
dx_parsed_field_t *child = dx_parse_internal(field->raw_iter, field);
DEQ_INSERT_TAIL(field->children, child);
@@ -377,4 +383,3 @@ dx_parsed_field_t *dx_parse_value_by_key(dx_parsed_field_t *field, const char *k
return 0;
}
-