overwriting a cbor map field result even though field is not decoded

hello Nordic

i am using ncs 2.8.0 with nrf52832 and mrf52840

i am decoding a cbor file with the 'zcbor_map_decode_bulk'

LOG_INF("in func decode config - val_9 %d", result->val_9_placeholder);

    ZCBOR_STATE_D(zsd, 2, config_file, config_file_len, 1, 0);
    struct zcbor_map_decode_key_val map_key_decode[] = {
        ZCBOR_MAP_DECODE_KEY_DECODER("..", zcbor_int32_decode, &result->..),
        ZCBOR_MAP_DECODE_KEY_DECODER("..", my_implementation_decode, &result->..),
        ZCBOR_MAP_DECODE_KEY_DECODER("..", my_implementation_decode, &result->..),
        ZCBOR_MAP_DECODE_KEY_DECODER("..", my_implementation_decode, &result->..),
        ZCBOR_MAP_DECODE_KEY_DECODER("..", my_implementation_decode, &result->..),
        ZCBOR_MAP_DECODE_KEY_DECODER("..", my_implementation_decode, &result->..),
        ZCBOR_MAP_DECODE_KEY_DECODER("..", zcbor_bool_decode, &result->..),
        ZCBOR_MAP_DECODE_KEY_DECODER("..", zcbor_bool_decode, &result->..),
        ZCBOR_MAP_DECODE_KEY_DECODER("val_9", zcbor_bool_decode, &result->val_9_placeholder),
        ZCBOR_MAP_DECODE_KEY_DECODER("..", zcbor_int32_decode, &result->battery_capacity),
    };

    int rc = zcbor_map_decode_bulk(zsd, map_key_decode, ARRAY_SIZE(map_key_decode), &decoded);

LOG_INF("decode config - val_9 %d, rc %d", result->val_9_placeholder, rc);

the 'my_implementation_decode' is just a function that has map with all zcbor_decode.h function calls and the same 'zcbor_map_decode_bulk' at the end.

for some reason the value of the result->val9_placeholder changes from the default '1' it was before decoding, to '0' after, though there is no field 'val_9' in the cbor file i am decoding 

and following the 'zcbor_map_decode_bulk' function, with log prints, shows that the val_9 never goes through  

dptr->decoder(zsd, dptr->value_ptr) ... it does not pass the condition 
if (key.len == dptr->key.len && memcmp(key.value, dptr->key.value, key.len) == 0)

any idea why the result->val9_placeholder  is changed anyway ?

p.s. it does not happen when there is a shorter cbor with less fields (the cbor with issues is 246 bytes, and the small cbor is 178) 

hope to read from you soon

best regards

ZIv 

  • Hello,

    I am not sure what the issue is, but could you add more detailed logging to the decoding function? Maybe adding logs at each step will help identify where the unexpected change to result->val_9_placeholder is originating from.

    Kind regards,
    Abhijith

  • the problem is that values of smaller size like uint8_t or uint16_t in the map, when decoded using zcbor_uint32_decode, cause over run of the other bytes, cause the function does a memset for 0 in the size of uint32 (4 bytes) so the values after the uint8_t, or uint16_t overrun with '0', if they are found in the cbor then they get new vals but else they get a '0'

    anyways, the solution use zcbor_uint_decode api .. which also gets the size of the value in bytes .. the problem is that the macro does not get another value so i had to create a wrapper for that function  like so:

    static bool augu_uint16_decode(zcbor_state_t *state, uint16_t *result)
    {
        return zcbor_uint_decode(state, result, sizeof(uint16_t));
    }
    
    static bool augu_uint8_decode(zcbor_state_t *state, uint8_t *result)
    {
        return zcbor_uint_decode(state, result, sizeof(uint8_t));
    }

    best regards

    Ziv

Related