lib/util: Input validation in str_to_uint
authorZoltan Kiss <zoltan.kiss@citrix.com>
Wed, 23 Apr 2014 13:45:21 +0000 (14:45 +0100)
committerBen Pfaff <blp@nicira.com>
Wed, 23 Apr 2014 18:46:55 +0000 (11:46 -0700)
This function returns true when 's' is negative or greater than UINT_MAX. Also,
the representation of 'int' and 'unsigned int' is implementation dependent, so
converting [INT_MAX..UINT_MAX] values with str_to_int is fragile.
Instead, we should convert straight to 'long long' and do a boundary check
before returning the converted value.
This patch also move the function to the .c file as it's not-trivial now, and
deletes the other str_to_u* functions as they are not used.

Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/util.c
lib/util.h

index 3f08c4a..1ebe22a 100644 (file)
@@ -613,6 +613,20 @@ str_to_llong(const char *s, int base, long long *x)
     }
 }
 
     }
 }
 
+bool
+str_to_uint(const char *s, int base, unsigned int *u)
+{
+    long long ll;
+    bool ok = str_to_llong(s, base, &ll);
+    if (!ok || ll < 0 || ll > UINT_MAX) {
+       *u = 0;
+       return false;
+    } else {
+       *u = ll;
+       return true;
+    }
+}
+
 /* Converts floating-point string 's' into a double.  If successful, stores
  * the double in '*d' and returns true; on failure, stores 0 in '*d' and
  * returns false.
 /* Converts floating-point string 's' into a double.  If successful, stores
  * the double in '*d' and returns true; on failure, stores 0 in '*d' and
  * returns false.
index aff17a5..bff6153 100644 (file)
@@ -290,24 +290,7 @@ void ovs_hex_dump(FILE *, const void *, size_t, uintptr_t offset, bool ascii);
 bool str_to_int(const char *, int base, int *);
 bool str_to_long(const char *, int base, long *);
 bool str_to_llong(const char *, int base, long long *);
 bool str_to_int(const char *, int base, int *);
 bool str_to_long(const char *, int base, long *);
 bool str_to_llong(const char *, int base, long long *);
-
-static inline bool
-str_to_uint(const char *s, int base, unsigned int *u)
-{
-    return str_to_int(s, base, (int *) u);
-}
-
-static inline bool
-str_to_ulong(const char *s, int base, unsigned long *ul)
-{
-    return str_to_long(s, base, (long *) ul);
-}
-
-static inline bool
-str_to_ullong(const char *s, int base, unsigned long long *ull)
-{
-    return str_to_llong(s, base, (long long *) ull);
-}
+bool str_to_uint(const char *, int base, unsigned int *);
 
 bool ovs_scan(const char *s, const char *format, ...) SCANF_FORMAT(2, 3);
 
 
 bool ovs_scan(const char *s, const char *format, ...) SCANF_FORMAT(2, 3);