This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/2] Parse hex and octal strings correctly in__strtoul_internal


Hi,

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. It looks like hexadecimal numbers
were never parsed in the linker anywhere and hence it got away with
this.

Attached patch adds validation for hexadecimal and octal values since
the next patch [2/2] looks to use this to parse hexadecimal numbers.
The test suite reports no regressions and the only place where the hex
logic is tested, i.e. [patch 2/2] works corectly with this fix.

Regards,
Siddhesh

ChangeLog:

2012-04-19  Siddhesh Poyarekar  <siddhesh@redhat.com>

	* elf/dl-minimal.c (__strtoul_internal): Parse hexadecimal and
	octal strings correctly.
diff --git a/elf/dl-minimal.c b/elf/dl-minimal.c
index 316de99..f538a60 100644
--- a/elf/dl-minimal.c
+++ b/elf/dl-minimal.c
@@ -264,11 +264,19 @@ __strtoul_internal (const char *nptr, char **endptr, int base, int group)
 	base = 8;
     }
 
-  while (*nptr >= '0' && *nptr <= '9')
+  while (1)
     {
-      unsigned long int digval = *nptr - '0';
-      if (result > ULONG_MAX / 10
-	  || (result == ULONG_MAX / 10 && digval > ULONG_MAX % 10))
+      unsigned long int digval;
+      unsigned max_digit = (base <= 10) ? base - 1 : 9;
+      if (*nptr >= '0' && *nptr <= '0' + max_digit)
+        digval = *nptr - '0';
+      else if (base == 16 && (*nptr >= 'a' && *nptr <= 'f'))
+        digval = *nptr - 'a' + 10;
+      else
+        break;
+
+      if (result > ULONG_MAX / base
+	  || (result == ULONG_MAX / base && digval > ULONG_MAX % base))
 	{
 	  errno = ERANGE;
 	  if (endptr != NULL)
-- 
1.7.7.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]