Fix decode functions for signed integers to prevent undefined behavior by using unsigned values (#1300)

This commit is contained in:
Steve Karg
2026-04-10 06:23:17 -05:00
committed by GitHub
parent f8bbc0b006
commit ba2d357784
+22 -13
View File
@@ -326,14 +326,17 @@ int encode_signed16(uint8_t *apdu, int16_t value)
int decode_signed16(const uint8_t *apdu, int32_t *value) int decode_signed16(const uint8_t *apdu, int32_t *value)
{ {
if (apdu && value) { if (apdu && value) {
uint32_t unsigned_value;
/* negative - bit 7 is set */ /* negative - bit 7 is set */
if (apdu[0] & 0x80) { if (apdu[0] & 0x80) {
*value = 0xFFFF0000; unsigned_value = 0xFFFF0000;
} else { } else {
*value = 0; unsigned_value = 0;
} }
*value |= (int32_t)apdu[0] << 8; unsigned_value |= (uint32_t)apdu[0] << 8;
*value |= (int32_t)apdu[1]; unsigned_value |= (uint32_t)apdu[1];
*value = (int32_t)unsigned_value;
} }
return 2; return 2;
@@ -353,15 +356,18 @@ int encode_signed24(uint8_t *apdu, int32_t value)
int decode_signed24(const uint8_t *apdu, int32_t *value) int decode_signed24(const uint8_t *apdu, int32_t *value)
{ {
if (apdu && value) { if (apdu && value) {
uint32_t unsigned_value;
/* negative - bit 7 is set */ /* negative - bit 7 is set */
if (apdu[0] & 0x80) { if (apdu[0] & 0x80) {
*value = 0xFF000000; unsigned_value = 0xFF000000;
} else { } else {
*value = 0; unsigned_value = 0;
} }
*value |= (int32_t)apdu[0] << 16; unsigned_value |= (uint32_t)apdu[0] << 16;
*value |= (int32_t)apdu[1] << 8; unsigned_value |= (uint32_t)apdu[1] << 8;
*value |= (int32_t)apdu[2]; unsigned_value |= (uint32_t)apdu[2];
*value = (int32_t)unsigned_value;
} }
return 3; return 3;
@@ -382,10 +388,13 @@ int encode_signed32(uint8_t *apdu, int32_t value)
int decode_signed32(const uint8_t *apdu, int32_t *value) int decode_signed32(const uint8_t *apdu, int32_t *value)
{ {
if (apdu && value) { if (apdu && value) {
*value = (int32_t)apdu[0] << 24; uint32_t unsigned_value;
*value |= (int32_t)apdu[1] << 16;
*value |= (int32_t)apdu[2] << 8; unsigned_value = (uint32_t)apdu[0] << 24;
*value |= (int32_t)apdu[3]; unsigned_value |= (uint32_t)apdu[1] << 16;
unsigned_value |= (uint32_t)apdu[2] << 8;
unsigned_value |= (uint32_t)apdu[3];
*value = (int32_t)unsigned_value;
} }
return 4; return 4;