]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[settings] Allow numeric_setting_value() to handle long setting values
authorMichael Brown <mcb30@ipxe.org>
Mon, 12 Aug 2013 17:23:25 +0000 (18:23 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 12 Aug 2013 17:25:18 +0000 (18:25 +0100)
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 <mcb30@ipxe.org>
src/core/settings.c
src/tests/settings_test.c

index 889e1078c7ff671d50857e291801c9b30db6b4aa..87de0d1b1b1dc089850e06d2c20dbcf0212a0c0b 100644 (file)
@@ -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;
index 670d549b92342b54b7e61e360e4803db5b6387c4..d1d923a4b3e3c7d1d1469d4268f594d2fa04b516 100644 (file)
@@ -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,