<regex>: Fix integer overflow in _Buf and implement geometric buffer expansion by muellerj2 · Pull Request #5175 · microsoft/STL (original) (raw)

Fixes an undetected integer overflow in _Buf::_Insert(_Elem) when increasing the buffer size.

It's unlikely anyone ever ran into this bug in practice, since the overflow could only happen following about 2282^{28}228 reallocations, but if one were to wait long enough, _Buf would write to and read from unallocated memory.

Since fixing the overflow bug meant rewriting the size calculations anyway, I also quickly added three lines to implement geometric expansion of the buffer, ensuring that inserting a new character runs in amortized constant rather than linear time. The selected growth factor is 1.5, same as vector's. (The geometric expansion kicks in when more than 48 characters are inserted into a character buffer. I think most practically used regular expressions don't even get close to adding 48 characters to one of these buffers.)

Finally, this PR makes _Buf throw a regex_error with error code error_space on allocation failure, which I think is the more appropriate exception when running out of memory while parsing a regular expression and building the corresponding NFA. But feel free to change this to bad_alloc etc. if you prefer these exceptions instead.

No tests added since they would require about 8 GB of virtual memory and run for several minutes, but here is a small x64 test program to see that overflow is handled correctly now:

#include #include #include

using namespace std;

int main() { { string s(static_cast(static_cast(-1)), 'a'); regex regex(s); }

{
    string s(static_cast<size_t>(static_cast<unsigned int>(-1)) + 1, 'a');
    try {
        regex regex(s);
        assert(false);
    } catch (const regex_error& ex) {
        assert(ex.code() == regex_constants::error_space);
    }
}
return 0;

}