Skip to content

Commit

Permalink
Fixed oer C code generation with sequences in additions (#168)
Browse files Browse the repository at this point in the history
* Added regression test for bug

* Require pyparsing <3.1

* Require protobuf <3.10
Require libsnmp<3

* Fixed compile errors

* Fixes #168

* Enabled uper C tests again and fixed them
  • Loading branch information
Futsch1 authored Oct 21, 2023
1 parent de25657 commit c890898
Show file tree
Hide file tree
Showing 14 changed files with 499 additions and 67 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ CC = gcc
endif

C_SOURCES := \
tests/files/c_source/oer.c
# tests/files/c_source/uper.c
tests/files/c_source/oer.c \
tests/files/c_source/uper.c

FUZZER_CC ?= clang
FUZZER_OER_EXE = main_oer_fuzzer
Expand Down
3 changes: 2 additions & 1 deletion asn1tools/source/c/oer.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,8 @@ def get_encoded_sequence_lengths(self, type_, checker):
lengths.append(get_sequence_present_mask_length(optionals,
extension_bit))
for member in type_.root_members:
lengths.extend(self.get_encoded_type_lengths(member, checker))
member_checker = self.get_member_checker(checker, member.name)
lengths.extend(self.get_encoded_type_lengths(member, member_checker))

if type_.additions is not None and len(type_.additions) > 0:
additions_mask_length = (
Expand Down
35 changes: 23 additions & 12 deletions asn1tools/source/c/uper.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def generate_definition_inner_process(self, type_, checker):
elif isinstance(type_, uper.OctetString):
return self.format_octet_string_inner(type_, checker)
elif isinstance(type_, uper.BitString):
return self.format_bit_string_inner(type_)
return self.format_bit_string_inner(type_, checker)
elif isinstance(type_, uper.Enumerated):
return self.format_enumerated_inner(type_)
elif isinstance(type_, uper.Null):
Expand Down Expand Up @@ -152,16 +152,19 @@ def format_integer_inner(self, type_, checker):
' {});'.format(type_.number_of_bits)
],
[
'dst_p->{} = decoder_read_non_negative_binary_integer('.format(
location),
'dst_p->{} = ({})decoder_read_non_negative_binary_integer('.format(
location,
type_name),
' decoder_p,',
' {});'.format(type_.number_of_bits),
'dst_p->{} += {};'.format(location, checker.minimum)
]
)

def format_bit_string_inner(self, type_):
def format_bit_string_inner(self, type_, checker):
location = self.location_inner()
max_value = 2 ** checker.minimum - 1
type_name = self.format_type_name(max_value, max_value)

return (
[
Expand All @@ -171,8 +174,9 @@ def format_bit_string_inner(self, type_):
' {});'.format(type_.maximum)
],
[
'dst_p->{} = decoder_read_non_negative_binary_integer('.format(
location),
'dst_p->{} = ({})decoder_read_non_negative_binary_integer('.format(
location,
type_name),
' decoder_p,',
' {});'.format(type_.maximum)
]
Expand Down Expand Up @@ -279,6 +283,10 @@ def format_sequence_inner(self, type_, checker):

def format_octet_string_inner(self, type_, checker):
location = self.location_inner('', '.')
if checker.maximum < 256:
length_type = 'uint8_t'
else:
length_type = 'uint32_t'

if checker.minimum == checker.maximum:
encode_lines = [
Expand All @@ -302,8 +310,9 @@ def format_octet_string_inner(self, type_, checker):
' src_p->{}length);'.format(location)
]
decode_lines = [
'dst_p->{}length = decoder_read_non_negative_binary_integer('.format(
location),
'dst_p->{}length = ({})decoder_read_non_negative_binary_integer('.format(
location,
length_type),
' decoder_p,',
' {});'.format(type_.number_of_bits),
'dst_p->{}length += {}u;'.format(location, checker.minimum)
Expand Down Expand Up @@ -459,8 +468,9 @@ def format_enumerated_inner(self, type_):
'{}, {});'.format(unique_value, type_.root_number_of_bits))

decode_lines = [
'{} = decoder_read_non_negative_binary_integer('
'{} = ({})decoder_read_non_negative_binary_integer('
'decoder_p, {});'.format(unique_value,
type_name,
type_.root_number_of_bits)
]

Expand Down Expand Up @@ -542,8 +552,9 @@ def format_sequence_of_inner(self, type_, checker):
location)
]
first_decode_lines = [
'dst_p->{}length = decoder_read_non_negative_binary_integer('.format(
location),
'dst_p->{}length = ({})decoder_read_non_negative_binary_integer('.format(
location,
type_name),
' decoder_p,',
' {});'.format(type_.number_of_bits),
'dst_p->{}length += {}u;'.format(location, checker.minimum),
Expand Down Expand Up @@ -596,7 +607,7 @@ def format_type_inner(self, type_, checker):
elif isinstance(type_, uper.Enumerated):
return self.format_enumerated_inner(type_)
elif isinstance(type_, uper.BitString):
return self.format_bit_string_inner(type_)
return self.format_bit_string_inner(type_, checker)
else:
raise self.error(type_)

Expand Down
2 changes: 1 addition & 1 deletion asn1tools/source/c/uper_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@
DECODER_READ_UINT8 = '''
static uint8_t decoder_read_uint8(struct decoder_t *self_p)
{
uint8_t value;
uint8_t value = 0;
decoder_read_bytes(self_p, &value, sizeof(value));
Expand Down
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
pyparsing>=3.0.6
pyparsing>=3.0.6,<3.1
codespell
pyasn1
asn1crypto
libsnmp
libsnmp<3
pysnmp
protobuf
protobuf<=3.20
prompt_toolkit[shell]
pycodestyle
bitstruct
Expand Down
7 changes: 7 additions & 0 deletions tests/files/c_source/c_source.asn
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,13 @@ AS ::= SEQUENCE {
a-c BOOLEAN DEFAULT TRUE
}

AT ::= SEQUENCE {
a INTEGER (0..127),
...,
b SEQUENCE (SIZE(1..32)) OF A OPTIONAL,
...
}

END

CRef DEFINITIONS AUTOMATIC TAGS ::=
Expand Down
177 changes: 176 additions & 1 deletion tests/files/c_source/oer.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
*/

/**
* This file was generated by asn1tools version 0.162.0 Fri May 6 17:18:21 2022.
* This file was generated by asn1tools version 0.166.0 Sat Oct 21 09:42:10 2023.
*/

#include <string.h>
Expand Down Expand Up @@ -4877,6 +4877,155 @@ static void oer_c_ref_at_decode_inner(
dst_p->value = (uint8_t)decoder_read_uint(decoder_p, 1);
}

static void oer_c_source_at_encode_inner(
struct encoder_t *encoder_p,
const struct oer_c_source_at_t *src_p)
{
uint8_t present_mask[1];
uint8_t addition_mask[1];
uint8_t number_of_length_bytes;
uint8_t i_2;

if(src_p->is_b_addition_present) {
present_mask[0] = 0x80;
}
else {
present_mask[0] = 0x0;
}

encoder_append_bytes(encoder_p,
&present_mask[0],
sizeof(present_mask));

encoder_append_uint8(encoder_p, src_p->a);

if((present_mask[0] & 0x80u) == 0x80u) {
encoder_append_length_determinant(encoder_p, 2);
encoder_append_uint8(encoder_p, 7);
addition_mask[0] = 0;

if (src_p->is_b_addition_present) {
addition_mask[0] |= 0x80u;
}
encoder_append_bytes(encoder_p,
&addition_mask[0],
sizeof(addition_mask));

if (src_p->is_b_addition_present) {
encoder_append_length_determinant(encoder_p, (uint32_t)minimum_uint_length(src_p->b.length) +
(uint32_t)(src_p->b.length * (42u)) + 1u);
number_of_length_bytes = minimum_uint_length(src_p->b.length);
encoder_append_uint8(encoder_p, number_of_length_bytes);
encoder_append_uint(encoder_p,
src_p->b.length,
number_of_length_bytes);

for (i_2 = 0; i_2 < src_p->b.length; i_2++) {
oer_c_source_a_encode_inner(encoder_p, &src_p->b.elements[i_2]);
}
}
}
}

static void oer_c_source_at_decode_inner(
struct decoder_t *decoder_p,
struct oer_c_source_at_t *dst_p)
{
uint8_t present_mask[1];
uint32_t addition_length;
uint8_t addition_unused_bits;
uint32_t addition_bits;
uint8_t addition_mask[1];
uint32_t i;
uint8_t tmp_addition_mask;
uint32_t unknown_addition_bits;
uint8_t mask;
uint8_t number_of_length_bytes;
uint8_t i_2;
uint32_t tmp_length;

decoder_read_bytes(decoder_p,
&present_mask[0],
sizeof(present_mask));

dst_p->a = decoder_read_uint8(decoder_p);

if((present_mask[0] & 0x80u) == 0x80u) {
addition_length = decoder_read_length_determinant(decoder_p);

if(addition_length <= 1u) {
decoder_abort(decoder_p, EBADLENGTH);

return;
}
addition_length -= 1u;
addition_unused_bits = decoder_read_uint8(decoder_p);

if (addition_unused_bits > 7u) {
decoder_abort(decoder_p, EBADLENGTH);

return;
}
addition_bits = ((addition_length * 8u) - addition_unused_bits);
decoder_read_bytes(decoder_p,
addition_mask,
(addition_length < 1u) ? addition_length : 1u);

tmp_addition_mask = addition_mask[0];
mask = 0x40;
unknown_addition_bits = 0;

for (i = 1; i < addition_bits; i++) {

if (mask == 0u) {
decoder_read_bytes(decoder_p, &tmp_addition_mask, 1);

if (decoder_get_result(decoder_p) < 0) {

return;
}
mask = 0x80;
}

if( (tmp_addition_mask & mask) == mask) {
unknown_addition_bits += 1u;
};
mask >>= 1;
}
dst_p->is_b_addition_present = ((addition_bits > 0u) && ((addition_mask[0] & 0x80u) == 0x80u));

if (dst_p->is_b_addition_present) {
(void)decoder_read_length_determinant(decoder_p);
number_of_length_bytes = decoder_read_uint8(decoder_p);
dst_p->b.length = (uint8_t)decoder_read_uint(
decoder_p,
number_of_length_bytes);

if (dst_p->b.length > 32u) {
decoder_abort(decoder_p, EBADLENGTH);

return;
}

for (i_2 = 0; i_2 < dst_p->b.length; i_2++) {
oer_c_source_a_decode_inner(decoder_p, &dst_p->b.elements[i_2]);
}
}

for (i = 0; i < unknown_addition_bits; i++) {
tmp_length = decoder_read_length_determinant(decoder_p);

if (decoder_free(decoder_p, tmp_length) < 0) {

return;
}
}
}
else {
dst_p->is_b_addition_present = false;
}
}

static void oer_c_ref_au_encode_inner(
struct encoder_t *encoder_p,
const struct oer_c_ref_au_t *src_p)
Expand Down Expand Up @@ -6482,6 +6631,32 @@ ssize_t oer_c_ref_at_decode(
return (decoder_get_result(&decoder));
}

ssize_t oer_c_source_at_encode(
uint8_t *dst_p,
size_t size,
const struct oer_c_source_at_t *src_p)
{
struct encoder_t encoder;

encoder_init(&encoder, dst_p, size);
oer_c_source_at_encode_inner(&encoder, src_p);

return (encoder_get_result(&encoder));
}

ssize_t oer_c_source_at_decode(
struct oer_c_source_at_t *dst_p,
const uint8_t *src_p,
size_t size)
{
struct decoder_t decoder;

decoder_init(&decoder, src_p, size);
oer_c_source_at_decode_inner(&decoder, dst_p);

return (decoder_get_result(&decoder));
}

ssize_t oer_c_ref_au_encode(
uint8_t *dst_p,
size_t size,
Expand Down
Loading

0 comments on commit c890898

Please sign in to comment.