vsapsai created this revision.

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


https://reviews.llvm.org/D40677

Files:
  libcxx/include/istream
  
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
  
libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp

Index: libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp
===================================================================
--- libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp
+++ libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size_chart.pass.cpp
@@ -7,13 +7,23 @@
 //
 //===----------------------------------------------------------------------===//
 
+// 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);
 
 #include <istream>
 #include <cassert>
 
+#include "test_macros.h"
+
 template <class CharT>
 struct testbuf
     : public std::basic_streambuf<CharT>
@@ -67,7 +77,33 @@
         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 @@
         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
 }
Index: libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
===================================================================
--- libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
+++ libcxx/test/std/input.output/iostream.format/input.streams/istream.unformatted/get_pointer_size.pass.cpp
@@ -7,13 +7,23 @@
 //
 //===----------------------------------------------------------------------===//
 
+// 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);
 
 #include <istream>
 #include <cassert>
 
+#include "test_macros.h"
+
 template <class CharT>
 struct testbuf
     : public std::basic_streambuf<CharT>
@@ -67,7 +77,33 @@
         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 @@
         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
 }
Index: libcxx/include/istream
===================================================================
--- libcxx/include/istream
+++ libcxx/include/istream
@@ -960,18 +960,25 @@
                     ++__gc_;
                      this->rdbuf()->sbumpc();
                 }
-                *__s = char_type();
                 if (__gc_ == 0)
                    __err |= ios_base::failbit;
                 this->setstate(__err);
             }
             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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to