Issue not all data was consumed in bstr .cbor X
map1 =
{
"1": int
}
Pet = bstr .cbor map1
generates
static bool decode_Pet(
zcbor_state_t *state, struct Pet *result)
{
zcbor_log("%s\r\n", __func__);
bool int_res;
bool res = (((zcbor_bstr_start_decode(state, &(*result).Pet)
&& (int_res = (((decode_map1(state, (&(*result).Pet_cbor))))), zcbor_bstr_end_decode(state), int_res))));
log_result(state, res, __func__);
return res;
}
NOTICE
if zcbor_bstr_end_decode(state) fails it does not result in an error
as such when
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zcbor_encode.h>
#include <stdio.h>
#include <stdint.h>
#include <pet_decode.h>
#include <pet_encode.h>
void testDecode(uint8_t * arr, size_t len)
{
int err;
struct Pet decoded_pet;
size_t processedLen = 0;
err = cbor_decode_Pet(arr, len, &decoded_pet, &processedLen);
if (err != ZCBOR_SUCCESS) {
printf("Decoding failed for pet1: %d\r\n", err);
return;
}
else
{
printf("SUCCESS %d %d\r\n", len, processedLen);
}
}
/** First pet - from var in pet1.h. */
static void get_pet1(void)
{
uint8_t mapLen1 = 0xa1;
uint8_t strLen1 = 0x61;
uint8_t zero = 0x0;
uint8_t bstr0 = 0x40;
#define MAP_1 mapLen1, strLen1, '1', zero
// NOTE zero, zero, zero is inside bstr0
uint8_t Pet[] = {bstr0 + 7, MAP_1, zero, zero, zero};
testDecode(Pet, sizeof(Pet));
}
void main(void)
{
get_pet1();
}
prints a processed length of less than the whole of the byte string
SUCCESS 8 5
This means that although the function return successfully
the payload and state are still inside the bstr decode state and are pointing to
uint8_t Pet[] = {bstr0 + 7, MAP_1,
zero, // <- payload and state point here
zero, zero};
and not to the end of the string, as one would expect if bstr has been decoded successfully
suggested fix: if zcbor_bstr_end_decode(state) fails return an error
Maybe also check you are in the bottom state when you finish decoding?
ISSUE 2 failed bstr .cbor X decode does not clean state up correctly
;
; Copyright (c) 2020 Nordic Semiconductor ASA
;
; SPDX-License-Identifier: Apache-2.0
;
map1 =
{
"1": int
}
map2 =
{
"2": int
}
Pet = {
"1" : (bstr .cbor map1 )/(bstr .cbor map2 )
}
See these 2 cases
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zcbor_encode.h>
#include <stdio.h>
#include <stdint.h>
#include <pet_decode.h>
#include <pet_encode.h>
void testDecode(uint8_t * arr, size_t len)
{
int err;
struct Pet decoded_pet;
size_t processedLen = 0;
err = cbor_decode_Pet(arr, len, &decoded_pet, &processedLen);
if (err != ZCBOR_SUCCESS) {
printf("Decoding failed for pet: %d\r\n", err);
return;
}
else
{
printf("pet SUCCESS\r\n");
}
}
/** First pet - from var in pet1.h. */
static void get_pet1(void)
{
uint8_t mapLen1 = 0xa1;
uint8_t strLen1 = 0x61;
uint8_t strLen0 = 0x60;
uint8_t zero = 0x0;
uint8_t bstr0 = 0x40;
#define MAP_1 mapLen1, strLen1, '1', zero
#define MAP_2 mapLen1, strLen1, '2', zero
uint8_t map1[] = {mapLen1, strLen1, '1', bstr0 + 4,MAP_1};
uint8_t map2[] = {mapLen1, strLen1, '1', bstr0 + 4,MAP_2};
testDecode(map1, sizeof(map1));
testDecode(map2, sizeof(map2));
}
void main(void)
{
get_pet1();
}
output
pet SUCCESS
Decoding failed for pet: 10
test case map2 fails, because it is first parsed as map1
zcbor_bstr_start_decode(state, &(*result).map1_bstr)
&& (int_res = (((decode_map1(state, (&(*result).map1_bstr_cbor))))), zcbor_bstr_end_decode(state), int_res)))
int_res is false,
so the state needs to be rewound
zcbor_bstr_end_decode(state) does not rewind the state because the payload is not fully consumed
Therefore the state is corrupted and won't be recoverd and decode fails
Suggested fix if (false == int_res) force zcbor_bstr_end_decode
Similarly
if zcbor_union_end_code returns an error is should be passed back up the chain
Issue not all data was consumed in bstr .cbor X
generates
NOTICE
if zcbor_bstr_end_decode(state) fails it does not result in an error
as such when
prints a processed length of less than the whole of the byte string
SUCCESS 8 5
This means that although the function return successfully
the payload and state are still inside the bstr decode state and are pointing to
and not to the end of the string, as one would expect if bstr has been decoded successfully
suggested fix: if zcbor_bstr_end_decode(state) fails return an error
Maybe also check you are in the bottom state when you finish decoding?
ISSUE 2 failed bstr .cbor X decode does not clean state up correctly
See these 2 cases
output
test case map2 fails, because it is first parsed as map1
int_res is false,
so the state needs to be rewound
zcbor_bstr_end_decode(state) does not rewind the state because the payload is not fully consumed
Therefore the state is corrupted and won't be recoverd and decode fails
Suggested fix if (false == int_res) force zcbor_bstr_end_decode
Similarly
if zcbor_union_end_code returns an error is should be passed back up the chain