diff options
author | Azat Khuzhin <a3at.mail@gmail.com> | 2023-05-17 09:16:54 -0700 |
---|---|---|
committer | Nikolas Klauser <n_klauser@apple.com> | 2023-05-17 09:21:04 -0700 |
commit | 53aed4759b33e33614e0f4e321bc1ef764b6d5b6 (patch) | |
tree | d200d8398b0f5ac0b3dc3494e50e6b85ee60903c /libcxx | |
parent | 0dc0c27989d3c26e677f3975d4911ffe72bdd8c1 (diff) | |
download | llvm-53aed4759b33e33614e0f4e321bc1ef764b6d5b6.tar.gz |
[libcxx] Fix crash in std::stringstream with payload >= INT_MAX
stringstream does works for payload > INT_MAX, however
stringstream::gcount() can break the internal field (__nout_) and this
breaks the stringstream itself, and so the program will crash.
Fix this, by using __pbump(streamsize) over pbump(int)
Note, libstdc++ does not have this bug.
Reviewed By: #libc, ldionne, Mordante
Spies: arichardson, Mordante, philnik, ldionne, libcxx-commits, mikhail.ramalho
Differential Revision: https://reviews.llvm.org/D146294
Diffstat (limited to 'libcxx')
-rw-r--r-- | libcxx/include/sstream | 2 | ||||
-rw-r--r-- | libcxx/test/std/input.output/string.streams/stringstream.members/gcount.pass.cpp | 41 |
2 files changed, 42 insertions, 1 deletions
diff --git a/libcxx/include/sstream b/libcxx/include/sstream index 6dd581e30cb4..26c899215322 100644 --- a/libcxx/include/sstream +++ b/libcxx/include/sstream @@ -646,7 +646,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off, if (__wch & ios_base::out) { this->setp(this->pbase(), this->epptr()); - this->pbump(__noff); + this->__pbump(__noff); } return pos_type(__noff); } diff --git a/libcxx/test/std/input.output/string.streams/stringstream.members/gcount.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream.members/gcount.pass.cpp new file mode 100644 index 000000000000..7dbd68ec4373 --- /dev/null +++ b/libcxx/test/std/input.output/string.streams/stringstream.members/gcount.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// All 32 bit arches that CI has: +// +// UNSUPPORTED: target=powerpc-ibm-aix +// UNSUPPORTED: target=armv7l-linux-gnueabihf +// UNSUPPORTED: target=armv8l-linux-gnueabihf +// UNSUPPORTED: target=i686-w64-windows-gnu + +// Test that tellp() does not break the stringstream after INT_MAX, due to use +// of pbump() that accept int. + +#include <cassert> +#include <climits> +#include <sstream> +#include <string> + +int main(int, char**) { + std::stringstream ss; + std::string payload(INT_MAX - 1, '\0'); + + ss.write(payload.data(), payload.size()); + assert(ss.tellp() == INT_MAX - 1); + + ss.write("a", 1); + assert(ss.tellp() == INT_MAX); + + ss.write("b", 1); + assert(ss.tellp() == INT_MAX + 1ULL); + // it fails only after previous tellp() corrupts the internal field with int + // overflow + assert(ss.tellp() == INT_MAX + 1ULL); + + return 0; +} |