[libcxx] r322326 - [libcxx] Make std::basic_istream::get 0-terminate input array in case of error.
Volodymyr Sapsai via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 11 15:23:49 PST 2018
Author: vsapsai
Date: Thu Jan 11 15:23:49 2018
New Revision: 322326
URL: http://llvm.org/viewvc/llvm-project?rev=322326&view=rev
Log:
[libcxx] Make std::basic_istream::get 0-terminate input array in case of error.
It covers the cases when the sentry object returns false and when an exception
was thrown. Corresponding standard paragraph is C++14 [istream.unformatted]p9:
[...] In any case, if n is greater than zero it then stores a null
character into the next successive location of the array.
rdar://problem/35566567
Reviewers: EricWF, mclow.lists
Reviewed By: mclow.lists
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D40677
Modified:
libcxx/trunk/include/istream
libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp
Modified: libcxx/trunk/include/istream
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/istream?rev=322326&r1=322325&r2=322326&view=diff
==============================================================================
--- libcxx/trunk/include/istream (original)
+++ libcxx/trunk/include/istream Thu Jan 11 15:23:49 2018
@@ -960,7 +960,6 @@ basic_istream<_CharT, _Traits>::get(char
++__gc_;
this->rdbuf()->sbumpc();
}
- *__s = char_type();
if (__gc_ == 0)
__err |= ios_base::failbit;
this->setstate(__err);
@@ -968,10 +967,14 @@ basic_istream<_CharT, _Traits>::get(char
else
this->setstate(ios_base::failbit);
}
+ if (__n > 0)
+ *__s = char_type();
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
+ if (__n > 0)
+ *__s = char_type();
this->__set_badbit_and_consider_rethrow();
}
#endif // _LIBCPP_NO_EXCEPTIONS
Modified: libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp?rev=322326&r1=322325&r2=322326&view=diff
==============================================================================
--- libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp (original)
+++ libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp Thu Jan 11 15:23:49 2018
@@ -7,6 +7,14 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: with_system_cxx_lib=macosx10.13
+// XFAIL: with_system_cxx_lib=macosx10.12
+// XFAIL: with_system_cxx_lib=macosx10.11
+// XFAIL: with_system_cxx_lib=macosx10.10
+// XFAIL: with_system_cxx_lib=macosx10.9
+// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: with_system_cxx_lib=macosx10.7
+
// <istream>
// basic_istream<charT,traits>& get(char_type* s, streamsize n);
@@ -14,6 +22,8 @@
#include <istream>
#include <cassert>
+#include "test_macros.h"
+
template <class CharT>
struct testbuf
: public std::basic_streambuf<CharT>
@@ -67,7 +77,33 @@ int main()
assert(!is.fail());
assert(std::string(s) == " ");
assert(is.gcount() == 1);
+ // Check that even in error case the buffer is properly 0-terminated.
+ is.get(s, 5);
+ assert( is.eof());
+ assert( is.fail());
+ assert(std::string(s) == "");
+ assert(is.gcount() == 0);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ testbuf<char> sb(" ");
+ std::istream is(&sb);
+ char s[5] = "test";
+ is.exceptions(std::istream::eofbit | std::istream::badbit);
+ try
+ {
+ is.get(s, 5);
+ assert(false);
+ }
+ catch (std::ios_base::failure&)
+ {
+ }
+ assert( is.eof());
+ assert( is.fail());
+ assert(std::string(s) == " ");
+ assert(is.gcount() == 1);
}
+#endif
{
testbuf<wchar_t> sb(L" \n \n ");
std::wistream is(&sb);
@@ -95,5 +131,31 @@ int main()
assert(!is.fail());
assert(std::wstring(s) == L" ");
assert(is.gcount() == 1);
+ // Check that even in error case the buffer is properly 0-terminated.
+ is.get(s, 5);
+ assert( is.eof());
+ assert( is.fail());
+ assert(std::wstring(s) == L"");
+ assert(is.gcount() == 0);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ testbuf<wchar_t> sb(L" ");
+ std::wistream is(&sb);
+ wchar_t s[5] = L"test";
+ is.exceptions(std::wistream::eofbit | std::wistream::badbit);
+ try
+ {
+ is.get(s, 5);
+ assert(false);
+ }
+ catch (std::ios_base::failure&)
+ {
+ }
+ assert( is.eof());
+ assert( is.fail());
+ assert(std::wstring(s) == L" ");
+ assert(is.gcount() == 1);
}
+#endif
}
Modified: libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp?rev=322326&r1=322325&r2=322326&view=diff
==============================================================================
--- libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp (original)
+++ libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp Thu Jan 11 15:23:49 2018
@@ -7,6 +7,14 @@
//
//===----------------------------------------------------------------------===//
+// XFAIL: with_system_cxx_lib=macosx10.13
+// XFAIL: with_system_cxx_lib=macosx10.12
+// XFAIL: with_system_cxx_lib=macosx10.11
+// XFAIL: with_system_cxx_lib=macosx10.10
+// XFAIL: with_system_cxx_lib=macosx10.9
+// XFAIL: with_system_cxx_lib=macosx10.8
+// XFAIL: with_system_cxx_lib=macosx10.7
+
// <istream>
// basic_istream<charT,traits>& get(char_type* s, streamsize n, char_type delim);
@@ -14,6 +22,8 @@
#include <istream>
#include <cassert>
+#include "test_macros.h"
+
template <class CharT>
struct testbuf
: public std::basic_streambuf<CharT>
@@ -67,7 +77,33 @@ int main()
assert(!is.fail());
assert(std::string(s) == " ");
assert(is.gcount() == 1);
+ // Check that even in error case the buffer is properly 0-terminated.
+ is.get(s, 5, '*');
+ assert( is.eof());
+ assert( is.fail());
+ assert(std::string(s) == "");
+ assert(is.gcount() == 0);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ testbuf<char> sb(" ");
+ std::istream is(&sb);
+ char s[5] = "test";
+ is.exceptions(std::istream::eofbit | std::istream::badbit);
+ try
+ {
+ is.get(s, 5, '*');
+ assert(false);
+ }
+ catch (std::ios_base::failure&)
+ {
+ }
+ assert( is.eof());
+ assert( is.fail());
+ assert(std::string(s) == " ");
+ assert(is.gcount() == 1);
}
+#endif
{
testbuf<wchar_t> sb(L" * * ");
std::wistream is(&sb);
@@ -95,5 +131,31 @@ int main()
assert(!is.fail());
assert(std::wstring(s) == L" ");
assert(is.gcount() == 1);
+ // Check that even in error case the buffer is properly 0-terminated.
+ is.get(s, 5, L'*');
+ assert( is.eof());
+ assert( is.fail());
+ assert(std::wstring(s) == L"");
+ assert(is.gcount() == 0);
+ }
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ testbuf<wchar_t> sb(L" ");
+ std::wistream is(&sb);
+ wchar_t s[5] = L"test";
+ is.exceptions(std::wistream::eofbit | std::wistream::badbit);
+ try
+ {
+ is.get(s, 5, L'*');
+ assert(false);
+ }
+ catch (std::ios_base::failure&)
+ {
+ }
+ assert( is.eof());
+ assert( is.fail());
+ assert(std::wstring(s) == L" ");
+ assert(is.gcount() == 1);
}
+#endif
}
More information about the cfe-commits
mailing list