esa / asn1scc

ASN1SCC: An open source ASN.1 compiler for embedded systems
https://www.thanassis.space/asn1.html
Other
272 stars 58 forks source link

XER decoding and -slim #298

Open GregoryEAllen opened 8 months ago

GregoryEAllen commented 8 months ago

When using -slim with XML, decoding is broken.

I defined a uint8 type: Uint8 ::= INTEGER (0..255) and got:

flag Uint8_XER_Decode_aux(Uint8* pVal, const char* xmlTag, ByteStream* pByteStrm, int* pErrCode)
{
    flag ret = TRUE;
    (void)pVal;
    (void)xmlTag;
    (void)pByteStrm;
    (void)pErrCode;

    ret = Xer_DecodePosInteger(pByteStrm, xmlTag, pVal, pErrCode);
    ret = true;
    *pErrCode = ret  ? 0 : ERR_XER_DECODE_UINT8;

    return ret;
}

This generated code assigns an asn1SccUint to the address of a uint8.

This causes a warning (breaking the automated test cases) and causes Uint8_XER_Decode_aux to write past the end of the uint8. When on the stack, this unexpectedly modifies the variable below it on the stack!

foo.c: In function ‘Uint8_XER_Decode_aux’:
foo.c:460:48: warning: passing argument 3 of ‘Xer_DecodePosInteger’ from incompatible pointer type [-Wincompatible-pointer-types]
  ret = Xer_DecodePosInteger(pByteStrm, xmlTag, pVal, pErrCode);
                                                ^~~~

A more correct solution is to follow the approach of BitStream_DecodeConstraintPosWholeNumberUInt8: use an asn1SccSint stack variable to temporarily hold the result before casting to the smaller type.

 flag Uint8_XER_Decode_aux(Uint8* pVal, const char* xmlTag, ByteStream* pByteStrm, int* pErrCode)
 {
    flag ret = TRUE;
    asn1SccSint val;
    (void)pVal;
    (void)xmlTag;
    (void)pByteStrm;
    (void)pErrCode;

    ret = Xer_DecodeInteger(pByteStrm, xmlTag, &val, pErrCode);
    *pVal = (Uint8)val;
    *pErrCode = ret  ? 0 : ERR_XER_DECODE_SINT8;

    return ret;
}

This would fix both the warning and the bug.