diff --git a/src/string_view.c b/src/string_view.c index 554294fa..bf6d7415 100644 --- a/src/string_view.c +++ b/src/string_view.c @@ -16,6 +16,7 @@ #include #include +#include #include "copy.inl" #include "equals.inl" @@ -101,9 +102,11 @@ char CpuFeatures_StringView_Back(const StringView view) { } StringView CpuFeatures_StringView_TrimWhitespace(StringView view) { - while (view.size && isspace(CpuFeatures_StringView_Front(view))) + while (view.size && + isspace((unsigned char)CpuFeatures_StringView_Front(view))) view = CpuFeatures_StringView_PopFront(view, 1); - while (view.size && isspace(CpuFeatures_StringView_Back(view))) + while (view.size && + isspace((unsigned char)CpuFeatures_StringView_Back(view))) view = CpuFeatures_StringView_PopBack(view, 1); return view; } @@ -115,14 +118,16 @@ static int HexValue(const char c) { return -1; } -// Returns -1 if view contains non digits. +// Returns -1 if view contains non digits, is empty, or overflows. static int ParsePositiveNumberWithBase(const StringView view, int base) { + if (view.size == 0) return -1; int result = 0; StringView remainder = view; for (; remainder.size; remainder = CpuFeatures_StringView_PopFront(remainder, 1)) { const int value = HexValue(CpuFeatures_StringView_Front(remainder)); if (value < 0 || value >= base) return -1; + if (result > (INT_MAX - value) / base) return -1; result = (result * base) + value; } return result; diff --git a/test/string_view_test.cc b/test/string_view_test.cc index 3af70c70..4e33de1f 100644 --- a/test/string_view_test.cc +++ b/test/string_view_test.cc @@ -124,19 +124,37 @@ TEST(StringViewTest, CpuFeatures_StringView_TrimWhitespace) { str("first middle last")); EXPECT_EQ(CpuFeatures_StringView_TrimWhitespace(str("first middle last")), str("first middle last")); + EXPECT_EQ(CpuFeatures_StringView_TrimWhitespace(str("")), str("")); + EXPECT_EQ(CpuFeatures_StringView_TrimWhitespace(str(" ")), str("")); + // Ensure non-ASCII characters (with high bit set) do not cause undefined behavior in isspace(). + EXPECT_EQ(CpuFeatures_StringView_TrimWhitespace(str(" \xff abc \x80 ")), + str("\xff abc \x80")); } TEST(StringViewTest, CpuFeatures_StringView_ParsePositiveNumber) { EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("42")), 42); + EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("0")), 0); + EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("0x0")), 0); EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("0x2a")), 42); EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("0x2A")), 42); EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("0x2A2a")), 10794); EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("0x2a2A")), 10794); + EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("0x")), -1); + EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("0x ")), -1); + EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("0xG")), -1); EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("-10")), -1); EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("-0x2A")), -1); EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("abc")), -1); EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber(str("")), -1); + + // Overflow handling + EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber( + str("999999999999999999999999999999")), + -1); + EXPECT_EQ(CpuFeatures_StringView_ParsePositiveNumber( + str("0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")), + -1); } TEST(StringViewTest, CpuFeatures_StringView_CopyString) {