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>
This commit is contained in:
Dan McArdle
2021-07-20 12:55:35 -04:00
committed by Boringssl LUCI CQ
parent 897a2ca3f1
commit 17be3872ab
+7 -3
View File
@@ -15,6 +15,7 @@
#include <string>
#include <vector>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@@ -92,13 +93,16 @@ bool GetUnsigned(unsigned *out, const std::string &arg_name,
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;
}