diff options
Diffstat (limited to 'drivers/acpi/utilities/utmisc.c')
-rw-r--r-- | drivers/acpi/utilities/utmisc.c | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 4d32f6d18f648..f6598547389b8 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -372,7 +372,7 @@ acpi_ut_strtoul64 ( u32 base, acpi_integer *ret_integer) { - u32 this_digit; + u32 this_digit = 0; acpi_integer return_value = 0; acpi_integer quotient; @@ -380,6 +380,10 @@ acpi_ut_strtoul64 ( ACPI_FUNCTION_TRACE ("ut_stroul64"); + if ((!string) || !(*string)) { + goto error_exit; + } + switch (base) { case ACPI_ANY_BASE: case 10: @@ -394,7 +398,7 @@ acpi_ut_strtoul64 ( /* Skip over any white space in the buffer */ while (ACPI_IS_SPACE (*string) || *string == '\t') { - ++string; + string++; } /* @@ -403,9 +407,9 @@ acpi_ut_strtoul64 ( */ if (base == 0) { if ((*string == '0') && - (ACPI_TOLOWER (*(++string)) == 'x')) { + (ACPI_TOLOWER (*(string + 1)) == 'x')) { base = 16; - ++string; + string += 2; } else { base = 10; @@ -416,10 +420,10 @@ acpi_ut_strtoul64 ( * For hexadecimal base, skip over the leading * 0 or 0x, if they are present. */ - if (base == 16 && - *string == '0' && - ACPI_TOLOWER (*(++string)) == 'x') { - string++; + if ((base == 16) && + (*string == '0') && + (ACPI_TOLOWER (*(string + 1)) == 'x')) { + string += 2; } /* Any string left? */ @@ -437,23 +441,27 @@ acpi_ut_strtoul64 ( this_digit = ((u8) *string) - '0'; } else { + if (base == 10) { + /* Digit is out of range */ + + goto error_exit; + } + this_digit = (u8) ACPI_TOUPPER (*string); - if (ACPI_IS_UPPER ((char) this_digit)) { + if (ACPI_IS_XDIGIT ((char) this_digit)) { /* Convert ASCII Hex char to value */ this_digit = this_digit - 'A' + 10; } else { - goto error_exit; + /* + * We allow non-hex chars, just stop now, same as end-of-string. + * See ACPI spec, string-to-integer conversion. + */ + break; } } - /* Check to see if digit is out of range */ - - if (this_digit >= base) { - goto error_exit; - } - /* Divide the digit into the correct position */ (void) acpi_ut_short_divide ((ACPI_INTEGER_MAX - (acpi_integer) this_digit), @@ -464,9 +472,11 @@ acpi_ut_strtoul64 ( return_value *= base; return_value += this_digit; - ++string; + string++; } + /* All done, normal exit */ + *ret_integer = return_value; return_ACPI_STATUS (AE_OK); |