Skip to content

Commit

Permalink
Fixing deserialization logic error in C (#232)
Browse files Browse the repository at this point in the history
* Fixing deserialization logic error in C

closes #221
Bump version number for release.

* Update src/nunavut/lang/c/templates/deserialization.j2

Co-authored-by: Pavel Kirienko <pavel.kirienko@gmail.com>

* fixing build and adding zero extension test

Co-authored-by: Pavel Kirienko <pavel.kirienko@gmail.com>
  • Loading branch information
thirtytwobits and pavel-kirienko committed Dec 16, 2021
1 parent 92b02ff commit 61232b3
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/nunavut/lang/c/templates/definitions.j2
Expand Up @@ -215,7 +215,7 @@ static inline {{ typename_error_type }} {{ t | full_reference_name }}_serialize_
/// @returns Negative on error, zero on success.
static inline {{ typename_error_type }} {{ t | full_reference_name }}_deserialize_(
{{ t | full_reference_name }}* const out_obj, {# -#}
const {{ typename_byte }}* const buffer, {# -#}
const {{ typename_byte }}* buffer, {# -#}
{{ typename_unsigned_length }}* const inout_buffer_size_bytes)
{
{% from 'deserialization.j2' import deserialize -%}
Expand Down
8 changes: 6 additions & 2 deletions src/nunavut/lang/c/templates/deserialization.j2
Expand Up @@ -11,11 +11,15 @@

{# ----------------------------------------------------------------------------------------------------------------- #}
{% macro deserialize(t) %}
if ((out_obj == {{ valuetoken_null }}) || (buffer == {{ valuetoken_null }}) || {# -#}
(inout_buffer_size_bytes == {{ valuetoken_null }}))
if ((out_obj == {{ valuetoken_null }}) || (inout_buffer_size_bytes == {{ valuetoken_null }}) || {# -#}
((buffer == {{ valuetoken_null }}) && (0 != *inout_buffer_size_bytes)))
{
return -NUNAVUT_ERROR_INVALID_ARGUMENT;
}
if (buffer == {{ valuetoken_null }})
{
buffer = (const {{ typename_byte }}*)"";
}
{% if t.inner_type.bit_length_set.max > 0 %}
{{ _deserialize_impl(t) }}
{% else %}
Expand Down
2 changes: 1 addition & 1 deletion src/nunavut/version.py
Expand Up @@ -7,7 +7,7 @@
.. autodata:: __version__
"""

__version__ = "1.6.1" #: The version number used in the release of nunavut to pypi.
__version__ = "1.6.2" #: The version number used in the release of nunavut to pypi.


__license__ = "MIT"
42 changes: 42 additions & 0 deletions verification/c/suite/test_serialization.c
Expand Up @@ -8,6 +8,7 @@
#include <regulated/basics/PrimitiveArrayVariable_0_1.h>
#include <regulated/delimited/A_1_0.h>
#include <regulated/delimited/A_1_1.h>
#include <uavcan/pnp/NodeIDAllocationData_2_0.h>
#include "unity.h" // Include 3rd-party headers afterward to ensure that our headers are self-sufficient.
#include <stdlib.h>
#include <time.h>
Expand Down Expand Up @@ -847,6 +848,45 @@ static void testPrimitiveArrayVariable(void)
}
}

/*
* Test that deserialization methods do not signal an error if a zero size is specified for a null output buffer.
*/
static void testIssue221(void)
{
uint8_t buf[regulated_basics_Primitive_0_1_SERIALIZATION_BUFFER_SIZE_BYTES_];
const size_t fixed_size = sizeof(buf);
size_t size = fixed_size;

regulated_basics_Primitive_0_1 obj;
TEST_ASSERT_EQUAL(0, regulated_basics_Primitive_0_1_deserialize_(&obj, &buf[0], &size));
size = fixed_size;
TEST_ASSERT_EQUAL(-NUNAVUT_ERROR_INVALID_ARGUMENT,
regulated_basics_Primitive_0_1_deserialize_(NULL, &buf[0], &size));
size = fixed_size;
TEST_ASSERT_EQUAL(-NUNAVUT_ERROR_INVALID_ARGUMENT,
regulated_basics_Primitive_0_1_deserialize_(&obj, NULL, &size));
TEST_ASSERT_EQUAL(-NUNAVUT_ERROR_INVALID_ARGUMENT,
regulated_basics_Primitive_0_1_deserialize_(&obj, &buf[0], NULL));
size = 0;
TEST_ASSERT_EQUAL(0,
regulated_basics_Primitive_0_1_deserialize_(&obj, NULL, &size));
TEST_ASSERT_EQUAL(0, size);
}

/*
* Ensure that, where there is no input data, the deserialization method applies the zero-extension rule as defined
* in section 3.7.1.4 of the specification.
*/
static void testIssue221_zeroExtensionRule(void)
{
size_t size = 0;
uavcan_pnp_NodeIDAllocationData_2_0 obj;
obj.node_id.value = 0xAAAA;
TEST_ASSERT_EQUAL(0, uavcan_pnp_NodeIDAllocationData_2_0_deserialize_(&obj, NULL, &size));
TEST_ASSERT_EQUAL(0, obj.node_id.value);
}


void setUp(void)
{
const unsigned seed = (unsigned) time(NULL);
Expand All @@ -869,6 +909,8 @@ int main(void)
RUN_TEST(testPrimitive);
RUN_TEST(testPrimitiveArrayFixed);
RUN_TEST(testPrimitiveArrayVariable);
RUN_TEST(testIssue221);
RUN_TEST(testIssue221_zeroExtensionRule);

return UNITY_END();
}

0 comments on commit 61232b3

Please sign in to comment.