diff options
Diffstat (limited to 'qpid/extras/dispatch/src/parse.c')
| -rw-r--r-- | qpid/extras/dispatch/src/parse.c | 29 |
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; } - |
