aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/settings.c8
-rw-r--r--src/tests/settings_test.c6
2 files changed, 10 insertions, 4 deletions
diff --git a/src/core/settings.c b/src/core/settings.c
index 889e1078..87de0d1b 100644
--- a/src/core/settings.c
+++ b/src/core/settings.c
@@ -862,18 +862,18 @@ static int numeric_setting_value ( int is_signed, const void *raw, size_t len,
const int8_t *signed_bytes = raw;
int is_negative;
unsigned int i;
+ uint8_t pad;
uint8_t byte;
- /* Range check */
- if ( len > sizeof ( long ) )
- return -ERANGE;
-
/* Convert to host-ordered longs */
is_negative = ( len && ( signed_bytes[0] < 0 ) );
*value = ( ( is_signed && is_negative ) ? -1L : 0 );
+ pad = *value;
for ( i = 0 ; i < len ; i++ ) {
byte = unsigned_bytes[i];
*value = ( ( *value << 8 ) | byte );
+ if ( ( ( i + sizeof ( *value ) ) < len ) && ( byte != pad ) )
+ return -ERANGE;
}
return len;
diff --git a/src/tests/settings_test.c b/src/tests/settings_test.c
index 670d549b..d1d923a4 100644
--- a/src/tests/settings_test.c
+++ b/src/tests/settings_test.c
@@ -342,6 +342,12 @@ static void settings_test_exec ( void ) {
RAW ( 0x98, 0xab, 0x41, 0x81 ), 0x98ab4181 );
fetchn_ok ( &test_settings, &test_uint32_setting,
RAW ( 0xff, 0xff, 0xfe ), 0x00fffffe );
+ fetchn_ok ( &test_settings, &test_uint32_setting,
+ RAW ( 0, 0, 0, 0x12, 0x34, 0x56, 0x78 ), 0x12345678 );
+ fetchn_ok ( &test_settings, &test_int32_setting,
+ RAW ( 0, 0, 0, 0x12, 0x34, 0x56, 0x78 ), 0x12345678 );
+ fetchn_ok ( &test_settings, &test_int32_setting,
+ RAW ( 0xff, 0xff, 0x87, 0x65, 0x43, 0x21 ), -0x789abcdf );
/* "hex" setting type */
storef_ok ( &test_settings, &test_hex_setting,