mouse07410 / asn1c

The ASN.1 Compiler
http://lionet.info/asn1c/
BSD 2-Clause "Simplified" License
94 stars 71 forks source link

ASN1C fails to decode some packets on an ARM cortex m4 #71

Closed mtfurlan closed 3 years ago

mtfurlan commented 3 years ago

We noticed an issue with decoding UPER encoded numbers into a long on an arm cortex-m4.

Problem Description

Our ASN field is

Longitude ::= INTEGER (-1799999999..1800000001)

asn1c typed Longitude as a long, which is reasonable, a long is

at least the [−2,147,483,647, +2,147,483,647] range

Notably, it can be bigger.

We noticed that we couldn't decode some UPER encoded longitudes, some quick experimentation later:

Working : 0x14B62E00
non :     0x14B62E01

It seems likely this is an issue with the size of a long.

amd64 (everything works as expected):  sizeof(long) = 8
arm cortex m4 nRf52840 (doesn't work): sizeof(long) = 4

If we change a cast from long to intmax_t, we can decode any valid value as expected.

diff --git a/test-asn/per_support.c b/test-asn/per_support.c
index f060f57..7e6eccf 100644
--- a/test-asn/per_support.c
+++ b/test-asn/per_support.c
@@ -294,7 +294,7 @@ per_imax_range_unrebase(uintmax_t inp, intmax_t lb, intmax_t ub, intmax_t *outp)
     }

     if(inp <= INTMAX_MAX) {
-        *outp = (long)inp + lb;
+        *outp = (intmax_t)inp + lb;
     } else {
         *outp = (lb + INTMAX_MAX + 1) + (intmax_t)((inp - INTMAX_MAX) - 1);
     }

The values around this cast are all intmax_t (or uintmax_t), which is defined as a long long, so at least 64 bits.

Made a repo to make reproducing this as easy as I can: https://github.com/tomeinc/nordic-asn1c-long-issue This does require you to have a nordic nRF52840-DK, if needed I can arrange getting one to somebody.

mouse07410 commented 3 years ago

@mtfurlan I applied the fix you proposed (branch vlm_master) - could you please confirm that it works as expected?

mtfurlan commented 3 years ago

That is working as expected here, many thanks!