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;
 }