From 55daa953fb82412e2e4dced4a39c6f7a3ff39b46 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 12 Aug 2013 18:23:25 +0100 Subject: [PATCH] [settings] Allow numeric_setting_value() to handle long setting values Allow numeric_setting_value() to handle e.g. the byte sequence 00:00:00:00:12:34:56:78 by returning -ERANGE only if the value actually overflows the return type. Signed-off-by: Michael Brown --- src/core/settings.c | 8 ++++---- src/tests/settings_test.c | 6 ++++++ 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,