Skip to content

Commit 9950d81

Browse files
committed
Indefinite maps decoding
1 parent 77e767a commit 9950d81

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed

src/cbor.c

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ cbor_item_t * cbor_load(cbor_data source,
9999
.indef_array_start = &cbor_builder_indef_array_start_callback,
100100

101101
.map_start = &cbor_builder_map_start_callback,
102+
.indef_map_start = &cbor_builder_indef_map_start_callback,
102103

103104
.tag = &cbor_builder_tag_callback,
104105

src/cbor_internal.c

+8-9
Original file line numberDiff line numberDiff line change
@@ -108,23 +108,22 @@ void _cbor_builder_append(cbor_item_t * item, struct _cbor_decoder_context * ctx
108108
}
109109
case CBOR_TYPE_MAP:
110110
{
111+
/* We use 0 and 1 subitems to distinguish between keys and values in indefinite items */
112+
if (ctx->stack->top->subitems % 2) {
113+
cbor_map_handle(ctx->stack->top->item)[cbor_map_size(ctx->stack->top->item) - 1].value = item;
114+
} else {
115+
/* Even record, this is a key */
116+
cbor_map_add(ctx->stack->top->item, (struct cbor_pair) {.key = item, .value = NULL});
117+
}
111118
if (cbor_map_is_definite(ctx->stack->top->item)) {
112-
assert(ctx->stack->top->subitems > 0);
113-
if (ctx->stack->top->subitems % 2) {
114-
// TODO this is fugly
115-
cbor_map_handle(ctx->stack->top->item)[cbor_map_size(ctx->stack->top->item) - 1].value = item;
116-
} else {
117-
/* Even record, this is a key */
118-
cbor_map_add(ctx->stack->top->item, (struct cbor_pair) {.key = item, .value = NULL});
119-
}
120119
ctx->stack->top->subitems--;
121120
if (ctx->stack->top->subitems == 0) {
122121
cbor_item_t *item = ctx->stack->top->item;
123122
_cbor_stack_pop(ctx->stack);
124123
_cbor_builder_append(item, ctx);
125124
}
126125
} else {
127-
// TODO uh oh
126+
ctx->stack->top->subitems ^= 1; /* Flip the indicator for indefinite items */
128127
}
129128
break;
130129
}

test/type_5_test.c

+21-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ static void test_simple_map(void **state)
3232
assert_non_null(map);
3333
assert_true(cbor_typeof(map) == CBOR_TYPE_MAP);
3434
assert_true(cbor_isa_map(map));
35+
assert_true(cbor_map_is_definite(map));
3536
assert_true(cbor_map_size(map) == 2);
3637
assert_true(res.read == 5);
3738
struct cbor_pair * handle = cbor_map_handle(map);
@@ -43,12 +44,30 @@ static void test_simple_map(void **state)
4344
assert_null(map);
4445
}
4546

46-
47+
unsigned char simple_indef_map[] = { 0xBF, 0x01, 0x02, 0x03, 0x04, 0xFF }; /* {_ 1: 2, 3: 4} */
48+
static void test_indef_simple_map(void **state)
49+
{
50+
map = cbor_load(simple_indef_map, 6, CBOR_FLAGS_NONE, &res);
51+
assert_non_null(map);
52+
assert_true(cbor_typeof(map) == CBOR_TYPE_MAP);
53+
assert_true(cbor_isa_map(map));
54+
assert_true(cbor_map_is_indefinite(map));
55+
assert_true(cbor_map_size(map) == 2);
56+
assert_true(res.read == 6);
57+
struct cbor_pair * handle = cbor_map_handle(map);
58+
assert_uint8(handle[0].key, 1);
59+
assert_uint8(handle[0].value, 2);
60+
assert_uint8(handle[1].key, 3);
61+
assert_uint8(handle[1].value, 4);
62+
cbor_decref(&map);
63+
assert_null(map);
64+
}
4765

4866
int main(void) {
4967
const UnitTest tests[] = {
5068
unit_test(test_empty_map),
51-
unit_test(test_simple_map)
69+
unit_test(test_simple_map),
70+
unit_test(test_indef_simple_map)
5271
};
5372
return run_tests(tests);
5473
}

0 commit comments

Comments
 (0)