diff --git a/src/string.cpp b/src/string.cpp index 0c5f06d..c884948 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -940,16 +940,18 @@ namespace bx else if ('%' == ch) { // %[flags][width][.precision][length sub-specifier]specifier - read(&reader, ch); + read(&reader, ch, &err); Param param; // flags - while (' ' == ch + while (err.isOk() + && ( ' ' == ch || '-' == ch || '+' == ch || '0' == ch || '#' == ch) + ) { switch (ch) { @@ -961,7 +963,7 @@ namespace bx case '#': param.spec = true; break; } - read(&reader, ch); + read(&reader, ch, &err); } if (param.left) @@ -972,7 +974,7 @@ namespace bx // width if ('*' == ch) { - read(&reader, ch); + read(&reader, ch, &err); param.width = va_arg(_argList, int32_t); if (0 > param.width) @@ -984,41 +986,45 @@ namespace bx } else { - while (isNumeric(ch) ) + while (err.isOk() + && isNumeric(ch) ) { param.width = param.width * 10 + ch - '0'; - read(&reader, ch); + read(&reader, ch, &err); } } // .precision if ('.' == ch) { - read(&reader, ch); + read(&reader, ch, &err); if ('*' == ch) { - read(&reader, ch); + read(&reader, ch, &err); param.prec = va_arg(_argList, int32_t); } else { param.prec = 0; - while (isNumeric(ch) ) + while (err.isOk() + && isNumeric(ch) ) { param.prec = param.prec * 10 + ch - '0'; - read(&reader, ch); + read(&reader, ch, &err); } } } // length sub-specifier - while ('h' == ch + while (err.isOk() + && ( 'h' == ch || 'I' == ch || 'l' == ch || 'j' == ch || 't' == ch || 'z' == ch) + ) { switch (ch) { @@ -1036,14 +1042,14 @@ namespace bx default: break; } - read(&reader, ch); + read(&reader, ch, &err); switch (ch) { case 'h': param.bits = sizeof(signed char )*8; break; case 'l': param.bits = sizeof(long long int)*8; break; case '3': case '6': - read(&reader, ch); + read(&reader, ch, &err); switch (ch) { case '2': param.bits = sizeof(int32_t)*8; break; @@ -1057,7 +1063,12 @@ namespace bx break; } - read(&reader, ch); + read(&reader, ch, &err); + } + + if (!err.isOk() ) + { + break; } // specifier diff --git a/tests/vsnprintf_test.cpp b/tests/vsnprintf_test.cpp index 8d09210..e65b70c 100644 --- a/tests/vsnprintf_test.cpp +++ b/tests/vsnprintf_test.cpp @@ -179,6 +179,13 @@ TEST_CASE("vsnprintf s") REQUIRE(test("(null)", "%s", NULL) ); } +TEST_CASE("vsnprintf t") +{ + size_t size = -1; + + REQUIRE(test("-1", "%td", size) ); +} + TEST_CASE("vsnprintf g") { REQUIRE(test(" 0.01", "%7.2g", .01) ); @@ -224,3 +231,15 @@ TEST_CASE("vsnprintf write") bx::StringView str(tmp, len); REQUIRE(0 == bx::strCmp(str, "1389") ); } + +TEST_CASE("snprintf invalid") +{ + char temp[64]; + REQUIRE(0 == bx::snprintf(temp, sizeof(temp), "%", 1) ); + REQUIRE(0 == bx::snprintf(temp, sizeof(temp), "%-", 1) ); + REQUIRE(0 == bx::snprintf(temp, sizeof(temp), "%-0", 1) ); + REQUIRE(0 == bx::snprintf(temp, sizeof(temp), "%-03", 1) ); + REQUIRE(0 == bx::snprintf(temp, sizeof(temp), "%-03.", 1) ); + REQUIRE(0 == bx::snprintf(temp, sizeof(temp), "%-03.0", 1) ); + REQUIRE(0 == bx::snprintf(temp, sizeof(temp), "%-03.0t", 1) ); +}