Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 32 additions & 4 deletions ext/cbor/unpacker.c
Original file line number Diff line number Diff line change
Expand Up @@ -703,24 +703,53 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
/* PRIMITIVE_OBJECT_COMPLETE */

if(msgpack_unpacker_stack_is_empty(uk)) {
if(r == PRIMITIVE_BREAK)
return PRIMITIVE_INVALID_BYTE;
return PRIMITIVE_OBJECT_COMPLETE;
}

container_completed:
{
msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk);

/* this section optimized out */
// TODO object_complete still creates objects which should be optimized out
/* XXX: check INDEF! */
if (top->type <= STACK_TYPE_MAP_VALUE_INDEF && r == PRIMITIVE_BREAK)
return PRIMITIVE_INVALID_BYTE;
switch(top->type) {
case STACK_TYPE_ARRAY_INDEF:
if (r == PRIMITIVE_BREAK)
goto complete;
continue;
case STACK_TYPE_MAP_KEY_INDEF:
if (r == PRIMITIVE_BREAK)
goto complete;
top->type = STACK_TYPE_MAP_VALUE_INDEF;
continue;
case STACK_TYPE_MAP_VALUE_INDEF:
top->type = STACK_TYPE_MAP_KEY_INDEF;
continue;
case STACK_TYPE_STRING_INDEF:
if (r == PRIMITIVE_BREAK)
goto complete;
if (!RB_TYPE_P(uk->last_object, T_STRING))
return PRIMITIVE_INVALID_BYTE;
#ifdef COMPAT_HAVE_ENCODING
if (ENCODING_GET(top->object) != ENCODING_GET(uk->last_object))
return PRIMITIVE_INVALID_BYTE;
#endif
continue;
default:
break;
}

size_t count = --top->count;

if(count == 0) {
complete:;
object_complete(uk, Qnil);
if(msgpack_unpacker_stack_pop(uk) <= target_stack_depth) {
return PRIMITIVE_OBJECT_COMPLETE;
}
r = PRIMITIVE_OBJECT_COMPLETE;
goto container_completed;
}
}
Expand Down Expand Up @@ -773,4 +802,3 @@ int msgpack_unpacker_skip_nil(msgpack_unpacker_t* uk)
}
return 0;
}