Fix decode functions for signed integers to prevent undefined behavior by using unsigned values (#1300)
This commit is contained in:
+22
-13
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user