schemagen: fix quadratic leading-zero strip in integer fallback
CI / build (-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++, clang-arm64, ubuntu-latest-arm64, true) (pull_request) Successful in 51s
CI / pre-commit (pull_request) Successful in 52s
CI / build (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc-arm64, ubuntu-latest-arm64, false) (pull_request) Successful in 51s
CI / build (-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++, clang-amd64, ubuntu-latest-amd64, true) (pull_request) Successful in 1m32s
CI / build (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc-amd64, ubuntu-latest-amd64, false) (pull_request) Successful in 1m26s
CI / build (-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++, clang-arm64, ubuntu-latest-arm64, true) (pull_request) Successful in 51s
CI / pre-commit (pull_request) Successful in 52s
CI / build (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc-arm64, ubuntu-latest-arm64, false) (pull_request) Successful in 51s
CI / build (-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++, clang-amd64, ubuntu-latest-amd64, true) (pull_request) Successful in 1m32s
CI / build (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc-amd64, ubuntu-latest-amd64, false) (pull_request) Successful in 1m26s
Replace the O(k^2) loop that erased leading zeros one byte at a time from the front of a std::string with a single linear scan and one erase(0, n) call. Also adds regression tests for issue #34: - correctness cases for numbers with leading fractional zeros - a static check that the generated code no longer contains the quadratic pattern - a large-input case (100k leading zeros) that reproduces the vulnerable shape Closes #34
This commit is contained in:
@@ -1000,8 +1000,10 @@ private:
|
||||
}}
|
||||
int64_t finalExp = exp - fracDigits + trim;
|
||||
if (finalExp < 0) return false;
|
||||
while (!digits.empty() && digits.front() == '0') digits.erase(digits.begin());
|
||||
if (digits.empty()) {{ out = 0; return true; }}
|
||||
size_t leadingZeros = 0;
|
||||
while (leadingZeros < digits.size() && digits[leadingZeros] == '0') ++leadingZeros;
|
||||
if (leadingZeros == digits.size()) {{ out = 0; return true; }}
|
||||
if (leadingZeros > 0) digits.erase(0, leadingZeros);
|
||||
|
||||
constexpr uint64_t kMaxNeg = 9223372036854775808ULL;
|
||||
constexpr uint64_t kMaxPos = 9223372036854775807ULL;
|
||||
|
||||
Reference in New Issue
Block a user