Fix undefined behaviour in left shifts
Due to the integer promotion rules of the C language, the unsigned char values are promoted to a signed integer (and not an unsigned integer) before being shifted. But the result of a left shift on a signed type is undefined if the resulting value can't be represented in the signed type. GCC's Undefined Behavior Sanitizer (ubsan), enabled with the option -fsanitize=undefined, detects this type of problem at runtime with the following warning: "left shift of X by Y places cannot be represented in type 'int'". Fixed with an explicit cast to unsigned integer.
This commit is contained in:
parent
43303eadf6
commit
ed21d776dd
33
src/array.c
33
src/array.c
@ -167,7 +167,7 @@ array_uint_be (const unsigned char data[], unsigned int n)
|
||||
unsigned int value = 0;
|
||||
for (unsigned int i = 0; i < n; ++i) {
|
||||
shift -= 8;
|
||||
value |= data[i] << shift;
|
||||
value |= (unsigned int) data[i] << shift;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@ -178,7 +178,7 @@ array_uint_le (const unsigned char data[], unsigned int n)
|
||||
unsigned int shift = 0;
|
||||
unsigned int value = 0;
|
||||
for (unsigned int i = 0; i < n; ++i) {
|
||||
value |= data[i] << shift;
|
||||
value |= (unsigned int) data[i] << shift;
|
||||
shift += 8;
|
||||
}
|
||||
return value;
|
||||
@ -187,21 +187,30 @@ array_uint_le (const unsigned char data[], unsigned int n)
|
||||
unsigned int
|
||||
array_uint32_be (const unsigned char data[])
|
||||
{
|
||||
return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
|
||||
return ((unsigned int) data[0] << 24) |
|
||||
((unsigned int) data[1] << 16) |
|
||||
((unsigned int) data[2] << 8) |
|
||||
((unsigned int) data[3] << 0);
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
array_uint32_le (const unsigned char data[])
|
||||
{
|
||||
return data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24);
|
||||
return ((unsigned int) data[0] << 0) |
|
||||
((unsigned int) data[1] << 8) |
|
||||
((unsigned int) data[2] << 16) |
|
||||
((unsigned int) data[3] << 24);
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
array_uint32_word_be (const unsigned char data[])
|
||||
{
|
||||
return data[1] + (data[0] << 8) + (data[3] << 16) + (data[2] << 24);
|
||||
return ((unsigned int) data[0] << 8) |
|
||||
((unsigned int) data[1] << 0) |
|
||||
((unsigned int) data[2] << 24) |
|
||||
((unsigned int) data[3] << 16);
|
||||
}
|
||||
|
||||
|
||||
@ -218,7 +227,9 @@ array_uint32_le_set (unsigned char data[], const unsigned int input)
|
||||
unsigned int
|
||||
array_uint24_be (const unsigned char data[])
|
||||
{
|
||||
return (data[0] << 16) + (data[1] << 8) + data[2];
|
||||
return ((unsigned int) data[0] << 16) |
|
||||
((unsigned int) data[1] << 8) |
|
||||
((unsigned int) data[2] << 0);
|
||||
}
|
||||
|
||||
|
||||
@ -234,20 +245,24 @@ array_uint24_be_set (unsigned char data[], const unsigned int input)
|
||||
unsigned int
|
||||
array_uint24_le (const unsigned char data[])
|
||||
{
|
||||
return data[0] + (data[1] << 8) + (data[2] << 16);
|
||||
return ((unsigned int) data[0] << 0) |
|
||||
((unsigned int) data[1] << 8) |
|
||||
((unsigned int) data[2] << 16);
|
||||
}
|
||||
|
||||
unsigned short
|
||||
array_uint16_be (const unsigned char data[])
|
||||
{
|
||||
return (data[0] << 8) + data[1];
|
||||
return ((unsigned int) data[0] << 8) |
|
||||
((unsigned int) data[1] << 0);
|
||||
}
|
||||
|
||||
|
||||
unsigned short
|
||||
array_uint16_le (const unsigned char data[])
|
||||
{
|
||||
return data[0] + (data[1] << 8);
|
||||
return ((unsigned int) data[0] << 0) |
|
||||
((unsigned int) data[1] << 8);
|
||||
}
|
||||
|
||||
unsigned char
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user