]> sjero.net Git - wget/commitdiff
[svn] Handle negative numbers and detect overflow in simple_atoi.
authorhniksic <devnull@localhost>
Sat, 19 Mar 2005 17:16:32 +0000 (09:16 -0800)
committerhniksic <devnull@localhost>
Sat, 19 Mar 2005 17:16:32 +0000 (09:16 -0800)
Handle negative numbers in simple_atof.

src/ChangeLog
src/init.c

index 7bb0aad27dd3ce229e20f3dc8e6d51608f17a8ee..fdd0a879dd1fa6b2702f6d23e2e5f13db24c051c 100644 (file)
@@ -1,3 +1,11 @@
+2005-03-12  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * init.c (simple_atof): Handle negative numbers; skip whitespace
+       before the number.
+       (simple_atoi): Ditto.  Also, check for overflow and underflow.
+       (cmd_number): Bail out on negative numbers.
+       (parse_bytes_helper): Ditto.
+
 2005-03-06  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * http.c (gethttp): Handle multiple Set-Cookie headers sent by
index 4c3356e1b0bcde2d4cfe2eb5840e272827f238f6..b504a27b36ef97497c2cb3c0c615f6146e0b9ef1 100644 (file)
@@ -689,7 +689,8 @@ static int simple_atoi PARAMS ((const char *, const char *, int *));
 static int
 cmd_number (const char *com, const char *val, void *closure)
 {
-  if (!simple_atoi (val, val + strlen (val), closure))
+  if (!simple_atoi (val, val + strlen (val), closure)
+      || *(int *) closure < 0)
     {
       fprintf (stderr, _("%s: %s: Invalid number `%s'.\n"),
               exec_name, com, val);
@@ -903,7 +904,7 @@ parse_bytes_helper (const char *val, double *result)
   if (val == end)
     return 0;
 
-  if (!simple_atof (val, end, &number))
+  if (!simple_atof (val, end, &number) || number < 0)
     return 0;
 
   *result = number * mult;
@@ -1189,21 +1190,46 @@ cmd_spec_useragent (const char *com, const char *val, void *closure)
 \f
 /* Miscellaneous useful routines.  */
 
-/* A very simple atoi clone, more portable than strtol and friends,
-   but reports errors, unlike atoi.  Returns 1 on success, 0 on
-   failure.  In case of success, stores result to *DEST.  */
+/* A very simple atoi clone, more useful than atoi because it works on
+   delimited strings, and has error reportage.  Returns 1 on success,
+   0 on failure.  If successful, stores result to *DEST.  */
 
 static int
 simple_atoi (const char *beg, const char *end, int *dest)
 {
   int result = 0;
-  const char *p;
+  int negative = 0;
+  const char *p = beg;
 
-  if (beg == end)
+  while (p < end && ISSPACE (*p))
+    ++p;
+  if (p < end && (*p == '-' || *p == '+'))
+    {
+      negative = (*p == '-');
+      ++p;
+    }
+  if (p == end)
     return 0;
 
-  for (p = beg; p < end && ISDIGIT (*p); p++)
-    result = (10 * result) + (*p - '0');
+  /* Read negative numbers in a separate loop because the most
+     negative integer cannot be represented as a positive number.  */
+
+  if (!negative)
+    for (; p < end && ISDIGIT (*p); p++)
+      {
+       int next = (10 * result) + (*p - '0');
+       if (next < result)
+         return 0;             /* overflow */
+       result = next;
+      }
+  else
+    for (; p < end && ISDIGIT (*p); p++)
+      {
+       int next = (10 * result) - (*p - '0');
+       if (next > result)
+         return 0;             /* underflow */
+       result = next;
+      }
 
   if (p != end)
     return 0;
@@ -1221,13 +1247,22 @@ simple_atof (const char *beg, const char *end, double *dest)
 {
   double result = 0;
 
+  int negative = 0;
   int seen_dot = 0;
   int seen_digit = 0;
   double divider = 1;
 
-  const char *p;
+  const char *p = beg;
+
+  while (p < end && ISSPACE (*p))
+    ++p;
+  if (p < end && (*p == '-' || *p == '+'))
+    {
+      negative = (*p == '-');
+      ++p;
+    }
 
-  for (p = beg; p < end; p++)
+  for (; p < end; p++)
     {
       char ch = *p;
       if (ISDIGIT (ch))
@@ -1250,6 +1285,8 @@ simple_atof (const char *beg, const char *end, double *dest)
     }
   if (!seen_digit)
     return 0;
+  if (negative)
+    result = -result;
 
   *dest = result;
   return 1;