libstdc++: Avoid overflow when appending to std::filesystem::path
commitd4cd871d15b813caa4b9016f34ebbda3277da4f8
authorJonathan Wakely <jwakely@redhat.com>
Fri, 5 Jan 2024 13:40:06 +0000 (5 13:40 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Fri, 5 Jan 2024 13:57:05 +0000 (5 13:57 +0000)
treeee505d6f053167855d536929753cb08b670966ee
parenta3fee5ef891cc8e4f39fe118ab5a3e875fcc7088
libstdc++: Avoid overflow when appending to std::filesystem::path

This prevents a std::filesystem::path from exceeding INT_MAX/4
components (which is unlikely to ever be a problem except on 16-bit
targets). That limit ensures that the capacity*1.5 calculation doesn't
overflow. We should also check that we don't exceed SIZE_MAX when
calculating how many bytes to allocate. That only needs to be checked
when int is at least as large as size_t, because otherwise we know that
the product INT_MAX/4 * sizeof(value_type) will fit in SIZE_MAX. For
targets where size_t is twice as wide as int this obviously holds. For
msp430-elf we have 16-bit int and 20-bit size_t, so the condition holds
as long as sizeof(value_type) fits in 7 bits, which it does.

We can also remove some floating-point arithmetic in operator/= which
ensures exponential growth of the buffer. That's redundant because
path::_List::reserve does that anyway (and does so more efficiently
since the commit immediately before this one).

libstdc++-v3/ChangeLog:

* src/c++17/fs_path.cc (path::_List::reserve): Limit maximum
size and check for overflows in arithmetic.
(path::operator/=(const path&)): Remove redundant exponential
growth calculation.
libstdc++-v3/src/c++17/fs_path.cc