*/
#define UCL_MAX_RECURSION 16
+#define UCL_MAX_NESTING 1024
#define UCL_TRASH_KEY 0
#define UCL_TRASH_VALUE 1
/* Bithack abs */
uval = ((val ^ (val >> 63)) - (val >> 63));
- if (val > -(1 << 5)) {
+ if (val >= -32) {
len = 1;
- buf[0] = (mask_negative | uval) & 0xff;
+ buf[0] = (uint8_t) (int8_t) val;
}
else if (uval <= INT8_MAX) {
uint8_t v = (uint8_t)val;
/*
* Insert new container to the stack
*/
+ unsigned int depth = 0;
+ struct ucl_stack *sp;
+ for (sp = parser->stack; sp != NULL; sp = sp->next) {
+ depth++;
+ }
+ if (depth >= UCL_MAX_NESTING) {
+ ucl_create_err(&parser->err,
+ "msgpack containers are nested too deep (over %d)",
+ UCL_MAX_NESTING);
+ return NULL;
+ }
+
if (parser->stack == NULL) {
parser->stack = calloc (1, sizeof (struct ucl_stack));
case 1:
len = *p;
break;
- case 2:
- len = FROM_BE16 (*(uint16_t *)p);
+ case 2: {
+ uint16_t v;
+ memcpy(&v, p, sizeof(v));
+ len = FROM_BE16(v);
break;
- case 4:
- len = FROM_BE32 (*(uint32_t *)p);
+ }
+ case 4: {
+ uint32_t v;
+ memcpy(&v, p, sizeof(v));
+ len = FROM_BE32(v);
break;
- case 8:
- len = FROM_BE64 (*(uint64_t *)p);
+ }
+ case 8: {
+ uint64_t v;
+ memcpy(&v, p, sizeof(v));
+ len = FROM_BE64(v);
break;
+ }
default:
ucl_create_err (&parser->err, "invalid length of the length field: %u",
(unsigned)obj_parser->len);
}
key = p;
- keylen = len;
- if (keylen > remain || keylen == 0) {
+ if (len == 0 || (int64_t) len > remain) {
ucl_create_err (&parser->err, "too long or empty key");
return false;
}
+ keylen = len;
p += len;
remain -= len;
len = 1;
break;
case msgpack_negative_fixint:
- obj->value.iv = - (*pos & 0x1f);
+ obj->value.iv = (int8_t) *pos;
len = 1;
break;
case msgpack_uint8:
p = chunk->pos;
+ if (p >= chunk->end) {
+ ucl_set_err(parser, UCL_ESYNTAX,
+ "unexpected end of input while parsing key",
+ &parser->err);
+ *end_of_object = true;
+ return true;
+ }
+
if (*p == '.' && !(parser->flags & UCL_PARSER_DISABLE_MACRO)) {
ucl_chunk_skipc(chunk, p);
parser->prev_state = parser->state;
p = chunk->pos;
/* Skip any spaces and comments */
- if (ucl_test_character(*p, UCL_CHARACTER_WHITESPACE_UNSAFE) ||
- (chunk->remain >= 2 && ucl_lex_is_comment(p[0], p[1]))) {
+ if (p < chunk->end &&
+ (ucl_test_character(*p, UCL_CHARACTER_WHITESPACE_UNSAFE) ||
+ (chunk->remain >= 2 && ucl_lex_is_comment(p[0], p[1])))) {
while (p < chunk->end && ucl_test_character(*p, UCL_CHARACTER_WHITESPACE_UNSAFE)) {
ucl_chunk_skipc(chunk, p);
}
p = chunk->pos;
+ if (p >= chunk->end) {
+ ucl_set_err(parser, UCL_ESYNTAX,
+ "unexpected end of input while parsing macro value",
+ &parser->err);
+ return false;
+ }
+
switch (*p) {
case '"':
/* We have macro value encoded in quotes */
}
ucl_chunk_skipc(chunk, p);
}
+ if (p >= chunk->end) {
+ ucl_set_err(parser, UCL_ESYNTAX,
+ "unterminated macro value, missing '}'",
+ &parser->err);
+ return false;
+ }
*macro_start = c;
*macro_len = p - c;
ucl_chunk_skipc(chunk, p);
saved.remain = chunk->remain;
p = chunk->pos;
- if (*p != '(' || chunk->remain < 2) {
+ if (chunk->remain < 2 || *p != '(') {
return NULL;
}
}
else {
/* Reset error */
- err->code = UCL_SCHEMA_OK;
+ if (err != NULL) {
+ err->code = UCL_SCHEMA_OK;
+ }
}
}
}
else {
/* Reset error */
- err->code = UCL_SCHEMA_OK;
+ if (err != NULL) {
+ err->code = UCL_SCHEMA_OK;
+ }
}
}
ucl_object_t *obj;
struct ucl_stack *st;
uint64_t len = 0;
+ unsigned int depth = 0;
enum {
start_parse,
read_obrace,
break;
case read_obrace:
+ if (depth >= UCL_MAX_NESTING) {
+ ucl_create_err(&parser->err,
+ "csexp nesting too deep (over %d)",
+ UCL_MAX_NESTING);
+ state = parse_err;
+ continue;
+ }
+
st = calloc(1, sizeof(*st));
if (st == NULL) {
LL_PREPEND(parser->stack, st);
}
+ depth++;
p++;
NEXT_STATE;
free(st);
st = NULL;
+ if (depth > 0) {
+ depth--;
+ }
p++;
NEXT_STATE;
break;