mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
Parse hexadecimal and octal strings correctly
The current implementation of __strtoul_internal seems to only pretend to support hex and octal strings by detecting a preceding 0x or 0 and marking base as 8 or 16. When it comes to the actual processing of the string, it only considers numeric values within, thus breaking hex values that may have [a-f] in them. Fixed with this commit.
This commit is contained in:
@ -1,3 +1,9 @@
|
|||||||
|
2012-04-25 Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||||
|
Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||||
|
|
||||||
|
* elf/dl-minimal.c (__strtoul_internal): Parse hexadecimal and octal
|
||||||
|
strings correctly.
|
||||||
|
|
||||||
2012-04-25 Chung-Lin Tang <cltang@codesourcery.com>
|
2012-04-25 Chung-Lin Tang <cltang@codesourcery.com>
|
||||||
|
|
||||||
* sysdeps/sh/memcpy.S: Remove include of endian.h, change
|
* sysdeps/sh/memcpy.S: Remove include of endian.h, change
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/* Minimal replacements for basic facilities used in the dynamic linker.
|
/* Minimal replacements for basic facilities used in the dynamic linker.
|
||||||
Copyright (C) 1995-1998,2000-2002,2004-2006,2007,2009
|
Copyright (C) 1995-2012 Free Software Foundation, Inc.
|
||||||
Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -232,6 +231,7 @@ __strtoul_internal (const char *nptr, char **endptr, int base, int group)
|
|||||||
{
|
{
|
||||||
unsigned long int result = 0;
|
unsigned long int result = 0;
|
||||||
long int sign = 1;
|
long int sign = 1;
|
||||||
|
unsigned max_digit;
|
||||||
|
|
||||||
while (*nptr == ' ' || *nptr == '\t')
|
while (*nptr == ' ' || *nptr == '\t')
|
||||||
++nptr;
|
++nptr;
|
||||||
@ -253,6 +253,7 @@ __strtoul_internal (const char *nptr, char **endptr, int base, int group)
|
|||||||
|
|
||||||
assert (base == 0);
|
assert (base == 0);
|
||||||
base = 10;
|
base = 10;
|
||||||
|
max_digit = 9;
|
||||||
if (*nptr == '0')
|
if (*nptr == '0')
|
||||||
{
|
{
|
||||||
if (nptr[1] == 'x' || nptr[1] == 'X')
|
if (nptr[1] == 'x' || nptr[1] == 'X')
|
||||||
@ -261,14 +262,31 @@ __strtoul_internal (const char *nptr, char **endptr, int base, int group)
|
|||||||
nptr += 2;
|
nptr += 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
base = 8;
|
{
|
||||||
|
base = 8;
|
||||||
|
max_digit = 7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*nptr >= '0' && *nptr <= '9')
|
while (1)
|
||||||
{
|
{
|
||||||
unsigned long int digval = *nptr - '0';
|
unsigned long int digval;
|
||||||
if (result > ULONG_MAX / 10
|
if (*nptr >= '0' && *nptr <= '0' + max_digit)
|
||||||
|| (result == ULONG_MAX / 10 && digval > ULONG_MAX % 10))
|
digval = *nptr - '0';
|
||||||
|
else if (base == 16)
|
||||||
|
{
|
||||||
|
if (*nptr >= 'a' && *nptr <= 'f')
|
||||||
|
digval = *nptr - 'a' + 10;
|
||||||
|
else if (*nptr >= 'A' && *nptr <= 'F')
|
||||||
|
digval = *nptr - 'A' + 10;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (result > ULONG_MAX / base
|
||||||
|
|| (result == ULONG_MAX / base && digval > ULONG_MAX % base))
|
||||||
{
|
{
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
if (endptr != NULL)
|
if (endptr != NULL)
|
||||||
|
Reference in New Issue
Block a user