[PATCH v3 04/13] loader: Refactor number parsing to own function.

Jinoh Kang jinoh.kang.kr at gmail.com
Tue Jan 25 09:24:50 CST 2022


Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---
 loader/preloader.c | 56 ++++++++++++++++++++++++++++++++--------------
 1 file changed, 39 insertions(+), 17 deletions(-)

diff --git a/loader/preloader.c b/loader/preloader.c
index 446e2f0e239..54a8b8bac2f 100644
--- a/loader/preloader.c
+++ b/loader/preloader.c
@@ -68,6 +68,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -715,6 +716,34 @@ static inline void *wld_memmove( void *dest, const void *src, size_t len )
     return dest;
 }
 
+static inline unsigned long parse_ul( const char *nptr, char **endptr, unsigned int radix, int *overflow )
+{
+    const char *p = nptr;
+    unsigned long value, thresh;
+    int ovfl = 0;
+
+    value = 0;
+    thresh = ULONG_MAX / radix;
+    for (;;)
+    {
+        unsigned int digit;
+        if (*p >= '0' && *p <= '9') digit = *p - '0';
+        else if (*p >= 'a' && *p <= 'z') digit = *p - 'a' + 10;
+        else if (*p >= 'A' && *p <= 'Z') digit = *p - 'A' + 10;
+        else break;
+        if (digit >= radix) break;
+        if (value > thresh) ovfl = 1;
+        value *= radix;
+        if (value > value + digit) ovfl = 1;
+        value += digit;
+        p++;
+    }
+
+    if (endptr) *endptr = (char *)p;
+    if (overflow) *overflow = ovfl;
+    return value;
+}
+
 /*
  * wld_printf - just the basics
  *
@@ -1357,29 +1386,22 @@ found:
  *
  * Reserve a range specified in string format
  */
-static void preload_reserve( const char *str )
+static void preload_reserve( char *str )
 {
-    const char *p;
+    char *p = str;
     unsigned long result = 0;
     void *start = NULL, *end = NULL;
-    int i, first = 1;
+    int i;
 
-    for (p = str; *p; p++)
+    result = parse_ul( p, &p, 16, NULL );
+    if (*p == '-')
     {
-        if (*p >= '0' && *p <= '9') result = result * 16 + *p - '0';
-        else if (*p >= 'a' && *p <= 'f') result = result * 16 + *p - 'a' + 10;
-        else if (*p >= 'A' && *p <= 'F') result = result * 16 + *p - 'A' + 10;
-        else if (*p == '-')
-        {
-            if (!first) goto error;
-            start = (void *)(result & ~page_mask);
-            result = 0;
-            first = 0;
-        }
-        else goto error;
+        start = (void *)(result & ~page_mask);
+        result = parse_ul( p + 1, &p, 16, NULL );
+        if (*p) goto error;
+        end = (void *)((result + page_mask) & ~page_mask);
     }
-    if (!first) end = (void *)((result + page_mask) & ~page_mask);
-    else if (result) goto error;  /* single value '0' is allowed */
+    else if (*p || result) goto error;  /* single value '0' is allowed */
 
     /* sanity checks */
     if (end <= start) start = end = NULL;
-- 
2.31.1




More information about the wine-devel mailing list