aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/std/istream
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2020-08-06 16:16:33 +0100
committerJonathan Wakely <jwakely@redhat.com>2020-08-06 18:26:45 +0100
commit6251ea15f55ec57d6325c2e37e88b22315aba658 (patch)
tree0f44c42a6daea85c951e58e781fb2a6c7f4bf37b /libstdc++-v3/include/std/istream
parent9c376d1c166e7c8b10bba6f1675d2471ffe8447f (diff)
downloadgcc-6251ea15f55ec57d6325c2e37e88b22315aba658.zip
gcc-6251ea15f55ec57d6325c2e37e88b22315aba658.tar.gz
gcc-6251ea15f55ec57d6325c2e37e88b22315aba658.tar.bz2
libstdc++: Adjust overflow prevention to operator>>
This adjusts the overflow prevention added to operator>> so that we can distinguish "unknown size" from "zero size", and avoid writing anything at all in to zero sized buffers. This also removes the incorrect comment saying extraction stops at a null byte. libstdc++-v3/ChangeLog: * include/std/istream (operator>>(istream&, char*)): Add attributes to get warnings for pointers that are null or known to point to the end of a buffer. Request upper bound from __builtin_object_size check and handle zero-sized buffer case. (operator>>(istream&, signed char)) (operator>>(istream&, unsigned char*)): Add attributes. * testsuite/27_io/basic_istream/extractors_character/char/overflow.cc: Check extracting into the middle of a buffer. * testsuite/27_io/basic_istream/extractors_character/wchar_t/overflow.cc: New test.
Diffstat (limited to 'libstdc++-v3/include/std/istream')
-rw-r--r--libstdc++-v3/include/std/istream26
1 files changed, 19 insertions, 7 deletions
diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream
index cb8e9f8..20a455a 100644
--- a/libstdc++-v3/include/std/istream
+++ b/libstdc++-v3/include/std/istream
@@ -790,7 +790,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* - `n - 1` characters are stored
* - EOF is reached
* - the next character is whitespace according to the current locale
- * - the next character is a null byte (i.e., `charT()`)
*
* `width(0)` is then called for the input stream.
*
@@ -799,25 +798,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus <= 201703L
template<typename _CharT, typename _Traits>
+ __attribute__((__nonnull__(2), __access__(__write_only__, 2)))
inline basic_istream<_CharT, _Traits>&
operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s)
{
- streamsize __n = __builtin_object_size(__s, 2) / sizeof(_CharT);
- if (__n == 0)
- __n = __gnu_cxx::__numeric_traits<streamsize>::__max / sizeof(_CharT);
- std::__istream_extract(__in, __s, __n);
+ size_t __n = __builtin_object_size(__s, 0);
+ if (__builtin_expect(__n < sizeof(_CharT), false))
+ {
+ // There is not even space for the required null terminator.
+ __glibcxx_assert(__n >= sizeof(_CharT));
+ __in.width(0);
+ __in.setstate(ios_base::failbit);
+ }
+ else
+ {
+ if (__n == (size_t)-1)
+ __n = __gnu_cxx::__numeric_traits<streamsize>::__max;
+ std::__istream_extract(__in, __s, __n / sizeof(_CharT));
+ }
return __in;
}
template<class _Traits>
+ __attribute__((__nonnull__(2), __access__(__write_only__, 2)))
inline basic_istream<char, _Traits>&
operator>>(basic_istream<char, _Traits>& __in, unsigned char* __s)
- { return (__in >> reinterpret_cast<char*>(__s)); }
+ { return __in >> reinterpret_cast<char*>(__s); }
template<class _Traits>
+ __attribute__((__nonnull__(2), __access__(__write_only__, 2)))
inline basic_istream<char, _Traits>&
operator>>(basic_istream<char, _Traits>& __in, signed char* __s)
- { return (__in >> reinterpret_cast<char*>(__s)); }
+ { return __in >> reinterpret_cast<char*>(__s); }
#else
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2499. operator>>(istream&, char*) makes it hard to avoid buffer overflows