Check strtoul return for overflow error in GetUnsigned()
Currently, GetUnsigned() calls strtoul and checks whether the resulting
unsigned long int is greater than UINT_MAX. This implicitly assumes that
UINT_MAX < ULONG_MAX.
Problematically, `unsigned long int` and `unsigned` have the same size
on Windows [0] and on 32-bit architectures.
For correctness, we now check whether strtoul failed because it would
overflow the unsigned long int before checking whether the value fits in
an unsigned type.
[0]: https://docs.microsoft.com/en-us/cpp/cpp/data-type-ranges?view=msvc-160
Change-Id: I49702febf4543bfb7991592717443e0b2adb954f
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/48545
Commit-Queue: Dan McArdle <dmcardle@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/tool/args.cc b/tool/args.cc
index 9ec18a3..4deb881 100644
--- a/tool/args.cc
+++ b/tool/args.cc
@@ -15,6 +15,7 @@
#include <string>
#include <vector>
+#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@@ -92,13 +93,16 @@
return false;
}
+ errno = 0;
char *endptr;
unsigned long int num = strtoul(value.c_str(), &endptr, 10);
- if (*endptr ||
- num > UINT_MAX) {
+ if (num == ULONG_MAX && errno == ERANGE) {
return false;
}
+ if (*endptr != 0 || num > UINT_MAX) {
+ return false;
+ }
+ *out = static_cast<unsigned>(num);
- *out = num;
return true;
}