backout scanner.l strtonum commits; they restrict numbers to INT_MAX,
authorsthen <sthen@openbsd.org>
Tue, 24 Sep 2024 14:20:31 +0000 (14:20 +0000)
committersthen <sthen@openbsd.org>
Tue, 24 Sep 2024 14:20:31 +0000 (14:20 +0000)
breaking filter expressions like "ether[14:4]=0xaaaa0300". ok op@ deraadt@

-/--------------------------
revision 1.32
date: 2024/08/29 07:33:50;  author: anton;  state: Exp;  lines: +2 -2;  commitid: ZYtBn8qrrNNh87on;
Fix regression introduced in previous migration to strtol() by
correcting the error condition, making it on par with the example in the
manual.

ok op@
-/--------------------------
revision 1.31
date: 2024/08/28 11:40:33;  author: op;  state: Exp;  lines: +13 -31;  commitid: RirJPBPfGo9NeSE6;
libpcap: replace hand-rolled number parser with strtol

can't use strtonum here since it needs to handle octal and hex
notations as well.  Part of a larger diff that's ok beck@
-/--------------------------

lib/libpcap/scanner.l

index 86a1936..0dcd6cc 100644 (file)
@@ -1,5 +1,5 @@
 %{
-/*     $OpenBSD: scanner.l,v 1.32 2024/08/29 07:33:50 anton Exp $      */
+/*     $OpenBSD: scanner.l,v 1.33 2024/09/24 14:20:31 sthen Exp $      */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -26,7 +26,6 @@
 #include <sys/time.h>
 
 #include <ctype.h>
-#include <limits.h>
 #include <string.h>
 #include <unistd.h>
 #include <vis.h>
@@ -48,6 +47,7 @@
 #include "grammar.h"
 
 static int stoi(char *);
+static inline int xdtoi(int);
 
 #ifdef FLEX_SCANNER
 #define YY_NO_UNPUT
@@ -333,23 +333,41 @@ yywrap(void)
        return 1;
 }
 
+/* Hex digit to integer. */
+static inline int
+xdtoi(int c)
+{
+       if (isdigit(c))
+               return c - '0';
+       else if (islower(c))
+               return c - 'a' + 10;
+       else
+               return c - 'A' + 10;
+}
+
 /*
- * Convert string to integer supporting also octal and hex notations.
+ * Convert string to integer.  Just like atoi(), but checks for
+ * preceding 0x or 0 and uses hex or octal instead of decimal.
  */
 static int
 stoi(char *s)
 {
-       long lval;
-       char *ep;
-
-       errno = 0;
-       lval = strtol(s, &ep, 0);
-       if (*s == '\0' || *ep != '\0')
-               bpf_error("invalid number %s", s);
-       if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN)) ||
-           (lval > INT_MAX || lval < INT_MIN))
-               bpf_error("out of range: %s", s);
-
-       return lval;
+       int base = 10;
+       int n = 0;
+
+       if (*s == '0') {
+               if (s[1] == 'x' || s[1] == 'X') {
+                       s += 2;
+                       base = 16;
+               }
+               else {
+                       base = 8;
+                       s += 1;
+               }
+       }
+       while (*s)
+               n = n * base + xdtoi(*s++);
+
+       return n;
 }