# std::from_chars
_ZSt10from_charsPKcS0_R[def]St12chars_format;
+ # std::__istream_extract(istream&, char*, streamsize)
+ _ZSt17__istream_extractRSiPc[ilx];
+ # std::__istream_extract(wistream&, wchar_t*, streamsize)
+ _ZSt17__istream_extractIwSt11char_traitsIwEEvRSt13basic_istreamIT_T0_EPS3_[ilx];
+
} GLIBCXX_3.4.28;
# Symbols in the support library (libsupc++) have their own tag.
}
template<typename _CharT, typename _Traits>
- basic_istream<_CharT, _Traits>&
- operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s)
+ void
+ __istream_extract(basic_istream<_CharT, _Traits>& __in, _CharT* __s,
+ streamsize __num)
{
typedef basic_istream<_CharT, _Traits> __istream_type;
typedef basic_streambuf<_CharT, _Traits> __streambuf_type;
__try
{
// Figure out how many characters to extract.
- streamsize __num = __in.width();
- if (__num <= 0)
- __num = __gnu_cxx::__numeric_traits<streamsize>::__max;
+ streamsize __width = __in.width();
+ if (0 < __width && __width < __num)
+ __num = __width;
const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
__err |= ios_base::failbit;
if (__err)
__in.setstate(__err);
- return __in;
}
// 27.6.1.4 Standard basic_istream manipulators
extern template class basic_istream<char>;
extern template istream& ws(istream&);
extern template istream& operator>>(istream&, char&);
- extern template istream& operator>>(istream&, char*);
extern template istream& operator>>(istream&, unsigned char&);
extern template istream& operator>>(istream&, signed char&);
- extern template istream& operator>>(istream&, unsigned char*);
- extern template istream& operator>>(istream&, signed char*);
extern template istream& istream::_M_extract(unsigned short&);
extern template istream& istream::_M_extract(unsigned int&);
extern template class basic_istream<wchar_t>;
extern template wistream& ws(wistream&);
extern template wistream& operator>>(wistream&, wchar_t&);
- extern template wistream& operator>>(wistream&, wchar_t*);
+ extern template void __istream_extract(wistream&, wchar_t*, streamsize);
extern template wistream& wistream::_M_extract(unsigned short&);
extern template wistream& wistream::_M_extract(unsigned int&);
{ return (__in >> reinterpret_cast<char&>(__c)); }
//@}
+
+ template<typename _CharT, typename _Traits>
+ void
+ __istream_extract(basic_istream<_CharT, _Traits>&, _CharT*, streamsize);
+
+ void __istream_extract(istream&, char*, streamsize);
+
//@{
/**
* @brief Character string extractors
* @param __in An input stream.
- * @param __s A pointer to a character array.
+ * @param __s A character array (or a pointer to an array before C++20).
* @return __in
*
* Behaves like one of the formatted arithmetic extractors described in
- * std::basic_istream. After constructing a sentry object with good
- * status, this function extracts up to @c n characters and stores them
- * into the array starting at @a __s. @c n is defined as:
+ * `std::basic_istream`. After constructing a sentry object with good
+ * status, this function extracts up to `n` characters and stores them
+ * into the array `__s`. `n` is defined as:
*
- * - if @c width() is greater than zero, @c n is width() otherwise
- * - @c n is <em>the number of elements of the largest array of *
- * - @c char_type that can store a terminating @c eos.</em>
- * - [27.6.1.2.3]/6
+ * - if `width()` is greater than zero, `n` is `min(width(), n)`
+ * - otherwise `n` is the number of elements of the array
+ * - (before C++20 the pointer is assumed to point to an array of
+ * - the largest possible size for an array of `char_type`).
*
* Characters are extracted and stored until one of the following happens:
- * - @c n-1 characters are stored
+ * - `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., @c charT() )
+ * - the next character is a null byte (i.e., `charT()`)
*
- * @c width(0) is then called for the input stream.
+ * `width(0)` is then called for the input stream.
*
* If no characters are extracted, sets failbit.
*/
- template<typename _CharT, typename _Traits>
- basic_istream<_CharT, _Traits>&
- operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s);
- // Explicit specialization declaration, defined in src/istream.cc.
- template<>
- basic_istream<char>&
- operator>>(basic_istream<char>& __in, char* __s);
+#if __cplusplus <= 201703L
+ template<typename _CharT, typename _Traits>
+ 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);
+ return __in;
+ }
template<class _Traits>
inline basic_istream<char, _Traits>&
inline basic_istream<char, _Traits>&
operator>>(basic_istream<char, _Traits>& __in, signed char* __s)
{ return (__in >> reinterpret_cast<char*>(__s)); }
+#else
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2499. operator>>(istream&, char*) makes it hard to avoid buffer overflows
+ template<typename _CharT, typename _Traits, size_t _Num>
+ inline basic_istream<_CharT, _Traits>&
+ operator>>(basic_istream<_CharT, _Traits>& __in, _CharT (&__s)[_Num])
+ {
+ static_assert(_Num <= __gnu_cxx::__numeric_traits<streamsize>::__max);
+ std::__istream_extract(__in, __s, _Num);
+ return __in;
+ }
+
+ template<class _Traits, size_t _Num>
+ inline basic_istream<char, _Traits>&
+ operator>>(basic_istream<char, _Traits>& __in, unsigned char (&__s)[_Num])
+ { return __in >> reinterpret_cast<char(&)[_Num]>(__s); }
+
+ template<class _Traits, size_t _Num>
+ inline basic_istream<char, _Traits>&
+ operator>>(basic_istream<char, _Traits>& __in, signed char (&__s)[_Num])
+ { return __in >> reinterpret_cast<char(&)[_Num]>(__s); }
+#endif
//@}
/**
void>::__type
advance(istreambuf_iterator<_CharT2>&, _Distance);
- template<typename _CharT2, typename _Traits2>
- friend basic_istream<_CharT2, _Traits2>&
- operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2*);
+ friend void __istream_extract(istream&, char*, streamsize);
template<typename _CharT2, typename _Traits2, typename _Alloc>
friend basic_istream<_CharT2, _Traits2>&
template istream& operator>>(istream&, char&);
template istream& operator>>(istream&, unsigned char&);
template istream& operator>>(istream&, signed char&);
+
+#if ! _GLIBCXX_INLINE_VERSION
+ // XXX GLIBCXX_ABI Deprecated
template istream& operator>>(istream&, char*);
template istream& operator>>(istream&, unsigned char*);
template istream& operator>>(istream&, signed char*);
+#endif
template istream& operator>>(istream&, _Setfill<char>);
template istream& operator>>(istream&, _Setiosflags);
template class basic_istream<wchar_t>;
template wistream& ws(wistream&);
template wistream& operator>>(wistream&, wchar_t&);
+ template void __istream_extract(wistream&, wchar_t*, streamsize);
+
+#if ! _GLIBCXX_INLINE_VERSION
+ // XXX GLIBCXX_ABI Deprecated
template wistream& operator>>(wistream&, wchar_t*);
+#endif
template wistream& operator>>(wistream&, _Setfill<wchar_t>);
template wistream& operator>>(wistream&, _Setiosflags);
return *this;
}
- template<>
- basic_istream<char>&
- operator>>(basic_istream<char>& __in, char* __s)
+ void
+ __istream_extract(istream& __in, char* __s, streamsize __num)
{
typedef basic_istream<char> __istream_type;
typedef __istream_type::int_type __int_type;
__try
{
// Figure out how many characters to extract.
- streamsize __num = __in.width();
- if (__num <= 0)
- __num = __gnu_cxx::__numeric_traits<streamsize>::__max;
+ streamsize __width = __in.width();
+ if (0 < __width && __width < __num)
+ __num = __width;
const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
__err |= ios_base::failbit;
if (__err)
__in.setstate(__err);
- return __in;
}
#ifdef _GLIBCXX_USE_WCHAR_T
// template<_CharT, _Traits>
// basic_istream& operator>>(istream&, _CharT*)
- int n = 20;
+ const int n = 20;
char array1[n];
typedef std::ios::traits_type ctraits_type;
// 27.6.1.2.3 basic_istream::operator>>
+// { dg-do run { target { ! c++20 } } }
// { dg-require-fileio "" }
#include <istream>
testthrow(c);
testthrow(uc);
testthrow(sc);
+#if __cplusplus <= 201703L
testthrow(cp);
testthrow(scp);
testthrow(ucp);
+#endif
return 0;
}
sstr >> str;
// 2
- pod_char* chr = 0;
+ pod_char chr[1];
sstr >> chr;
// 3
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+// LWG 2499
+// operator>>(basic_istream&, CharT*) makes it hard to avoid buffer overflows
+
+#include <sstream>
+#include <testsuite_hooks.h>
+
+template<typename T>
+void
+test(std::basic_istream<char, T>& in)
+{
+ char pc[3];
+ in >> pc;
+ VERIFY( in.good() );
+ VERIFY( pc[0] == 'a' && pc[1] == 'b' && pc[2] == '\0' );
+
+ signed char sc[4];
+ in >> sc;
+ VERIFY( in.good() );
+ VERIFY( sc[0] == 'c' && sc[1] == 'd' && sc[2] == 'e' && sc[3] == '\0' );
+
+ unsigned char uc[4];
+ in >> uc;
+ VERIFY( in.good() );
+ VERIFY( uc[0] == 'f' && uc[1] == 'g' && uc[2] == 'h' && uc[3] == '\0' );
+
+ pc[2] = '#';
+ in >> pc;
+ VERIFY( in.good() );
+ VERIFY( pc[0] == 'i' && pc[1] == '\0' && pc[2] == '#' );
+
+ in >> pc;
+ VERIFY( in.good() );
+ VERIFY( pc[0] == 'j' && pc[1] == 'k' && pc[2] == '\0' );
+
+ pc[2] = '#';
+ in >> pc;
+ VERIFY( in.eof() );
+ VERIFY( pc[0] == 'l' && pc[1] == '\0' && pc[2] == '#' );
+}
+
+void
+test01()
+{
+ std::istringstream in("abcdefghi jk l");
+ test(in);
+}
+
+void
+test02()
+{
+ struct CT : std::char_traits<char> { };
+ std::basic_istringstream<char, CT> in("abcdefghi jk l");
+ test(in);
+}
+
+int main()
+{
+ test01();
+ test02();
+}
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// LWG 2499
+// operator>>(basic_istream&, CharT*) makes it hard to avoid buffer overflows
+
+#include <istream>
+
+void
+test01(std::istream& in, char* pc, signed char* sc, unsigned char* uc)
+{
+ in >> pc; // { dg-error "here" }
+ in >> sc; // { dg-error "here" }
+ in >> uc; // { dg-error "here" }
+}
+
+struct CT : std::char_traits<char> { };
+
+void
+test02(std::basic_istream<char, CT>& in, char* pc, signed char* sc,
+ unsigned char* uc)
+{
+ in >> pc; // { dg-error "here" }
+ in >> sc; // { dg-error "here" }
+ in >> uc; // { dg-error "here" }
+}
+
+// { dg-excess-errors "" }
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-O2 -std=gnu++98" }
+// { dg-do run }
+
+// This test checks that operator>> will avoid a buffer overflow when
+// reading into a buffer with a size that is known at compile time.
+
+// Since C++20 this is guaranteed (see LWG 2499), for previous standards
+// we try to check the buffer size as an extension (which depends on -O2).
+
+#include <sstream>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::istringstream in("foolish child");
+ char pc[5];
+ in >> pc;
+ VERIFY( in.good() );
+ VERIFY( std::string(pc) == "fool" );
+}
+
+void
+test02()
+{
+ std::istringstream in("foolish");
+ signed char sc[5];
+ in >> sc;
+ VERIFY( in.good() );
+ VERIFY( std::string((const char*)sc) == "fool" );
+}
+
+void
+test03()
+{
+ std::istringstream in("foolish");
+ unsigned char uc[5];
+ in >> uc;
+ VERIFY( in.good() );
+ VERIFY( std::string((const char*)uc) == "fool" );
+}
+
+int
+main()
+{
+ test01();
+}
// template<_CharT, _Traits>
// basic_istream& operator>>(istream&, _CharT*)
- int n = 20;
+ const int n = 20;
wchar_t array1[n];
typedef std::wios::traits_type ctraits_type;
// 27.6.1.2.3 basic_istream::operator>>
// { dg-options "-DMAX_SIZE=466" { target simulator } }
+// { dg-do run { target { ! c++20 } } }
// { dg-require-fileio "" }
#ifndef MAX_SIZE
wchar_t* cp = &c;
testthrow(c);
+#if __cplusplus <= 201703L
testthrow(cp);
+#endif
return 0;
}
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// LWG 2499
+// operator>>(basic_istream&, CharT*) makes it hard to avoid buffer overflows
+
+#include <sstream>
+#include <testsuite_hooks.h>
+
+template<typename T>
+void
+test(std::basic_istream<wchar_t, T>& in)
+{
+ wchar_t wc[3];
+ in >> wc;
+ VERIFY( in.good() );
+ VERIFY( wc[0] == L'a' && wc[1] == L'b' && wc[2] == L'\0' );
+
+ wc[2] = L'#';
+ in >> wc;
+ VERIFY( in.good() );
+ VERIFY( wc[0] == L'c' && wc[1] == L'\0' && wc[2] == L'#' );
+
+ in >> wc;
+ VERIFY( in.good() );
+ VERIFY( wc[0] == L'd' && wc[1] == L'\0' && wc[2] == L'#' );
+
+ wc[2] = L'#';
+ in >> wc;
+ VERIFY( in.eof() );
+ VERIFY( wc[0] == L'e' && wc[1] == L'\0' && wc[2] == L'#' );
+}
+
+void
+test01()
+{
+ std::wistringstream in(L"abc d e");
+ test(in);
+}
+
+void
+test02()
+{
+ struct WT : std::char_traits<wchar_t> { };
+ std::basic_istringstream<wchar_t, WT> in(L"abc d e");
+ test(in);
+}
+
+int main()
+{
+ test01();
+ test02();
+}
--- /dev/null
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// LWG 2499
+// operator>>(basic_istream&, CharT*) makes it hard to avoid buffer overflows
+
+#include <istream>
+
+void
+test01(std::wistream& in, wchar_t* wc)
+{
+ in >> wc; // { dg-error "here" }
+}
+
+struct WT : std::char_traits<wchar_t> { };
+
+void
+test02(std::basic_istream<wchar_t, WT>& in, wchar_t* wc)
+{
+ in >> wc; // { dg-error "here" }
+}
+
+// { dg-excess-errors "" }