This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 3/4] Fix undefined behaviour in libstdc++ testsuite


This one's a bit more involved. There are a number of calls to
char_traits<>::copy() and char_traits<>::compare() that incorrectly
use the length of the larger array, not the shorter one.

The specialization in testsuite/util/testsuite_character.cc was
setting a null terminator after the numpunct atoms, past the end of he
array.

   Fix out-of-bound array accesses in libstdc++ testsuite
* testsuite/21_strings/basic_string/modifiers/append/char/1.cc: Fix
   	reads past the end of strings.
   	* testsuite/21_strings/basic_string/operations/compare/char/1.cc:
   	Likewise.
   	* testsuite/21_strings/char_traits/requirements/short/1.cc: Fix
   	invalid array accesses.
   	* testsuite/experimental/string_view/operations/compare/char/1.cc:
   	Fix read past the end of string.
   	* testsuite/util/testsuite_character.cc: Fix out-of-bounds write.


Tested powerpc64-linux, committed to trunk.
commit 11b5af6effaeb61d7a53dfc7fd6905d6cdd887e8
Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Thu Jul 21 19:38:51 2016 +0000

    Fix out-of-bound array accesses in libstdc++ testsuite
    
    	* testsuite/21_strings/basic_string/modifiers/append/char/1.cc: Fix
    	reads past the end of strings.
    	* testsuite/21_strings/basic_string/operations/compare/char/1.cc:
    	Likewise.
    	* testsuite/21_strings/char_traits/requirements/short/1.cc: Fix
    	invalid array accesses.
    	* testsuite/experimental/string_view/operations/compare/char/1.cc:
    	Fix read past the end of string.
    	* testsuite/util/testsuite_character.cc: Fix out-of-bounds write.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@238609 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/char/1.cc
index 176c317..1ccb9da 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/char/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/append/char/1.cc
@@ -118,7 +118,7 @@ bool test01(void)
   VERIFY( str06 == "corpus, corpus" );
 
   str06 = str02;
-  str06.append("corpus, ", 12);
+  str06.append("corpus, ", 9); // n=9 includes null terminator
   VERIFY( str06 != "corpus, corpus, " );
 
 
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/operations/compare/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/operations/compare/char/1.cc
index 55027b3..7fe30a7 100644
--- a/libstdc++-v3/testsuite/21_strings/basic_string/operations/compare/char/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/operations/compare/char/1.cc
@@ -80,10 +80,10 @@ test01()
   test_value(strcmp(str_1.data(), str_0.data()), lt);
   test_value(strcmp(str_0.data(), str_1.data()), gt);
   test_value(strncmp(str_1.data(), str_0.data(), 6), z);
-  test_value(strncmp(str_1.data(), str_0.data(), 14), lt);
+  test_value(strncmp(str_1.data(), str_0.data(), 10), lt);
   test_value(memcmp(str_1.data(), str_0.data(), 6), z);
-  test_value(memcmp(str_1.data(), str_0.data(), 14), lt);
-  test_value(memcmp("costa marbella", "costa rica", 14), lt);
+  test_value(memcmp(str_1.data(), str_0.data(), 10), lt);
+  test_value(memcmp("costa marbella", "costa rica", 10), lt);
 
   // int compare(const basic_string& str) const;
   test_value(str_0.compare(str_1), gt); //because r>m
diff --git a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/short/1.cc b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/short/1.cc
index 5b715a0..0a2d2ee 100644
--- a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/short/1.cc
+++ b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/short/1.cc
@@ -75,10 +75,11 @@ void test02(void)
 
   const char_type str_lit1[] = {'m', 'o', 'n', 't', 'a', 'r', 'a', ' ', 'a', 'n', 'd', ' ', 'o', 'c', 'e', 'a', 'n', ' ', 'b', 'e', 'a', 'c', 'h', 0};
 
-  int len = sizeof(str_lit1)/sizeof(char_type) + sizeof(array1)/sizeof(char_type) - 1;
+  const int array2_len = sizeof(str_lit1)/sizeof(char_type) + sizeof(array1)/sizeof(char_type) - 1;
   // two terminating chars
   char_type array3[] = {'b', 'o', 'r', 'a', 'c', 'a', 'y', ',', ' ', 'p', 'h', 'i', 'l', 'i', 'p', 'p', 'i', 'n', 'e', 's', 0};
-  char_type array2[len];
+  char_type array2[array2_len];
+  int len = std::min<int>(array2_len, sizeof(array3)/sizeof(char_type));
   std::char_traits<char_type>::copy(array2, array3, len);
 
   VERIFY( str_lit1[0] == 'm' );
@@ -139,13 +140,12 @@ void test02(void)
   VERIFY( pc4 == 0 );
 
   // char_type* X::assign(char_type* s, size_t n, char_type c)
-  len = sizeof(array2) / sizeof(char_type);
-  std::memset(array2, 0xaf, len * sizeof(char_type));
+  std::memset(array2, 0xaf, array2_len * sizeof(char_type));
   VERIFY( array2[0] != 0x15a8 );
 
-  pc1 = std::char_traits<char_type>::assign (array2, len, 0x15a8);
+  pc1 = std::char_traits<char_type>::assign (array2, array2_len, 0x15a8);
   VERIFY( pc1 == array2 );
-  for (int i = 0; i < len; ++i)
+  for (int i = 0; i < array2_len; ++i)
     VERIFY( array2[i] == 0x15a8 );
 
   // char_type* X::copy(char_type* s, const char_type* p, size_t n)
diff --git a/libstdc++-v3/testsuite/experimental/string_view/operations/compare/char/1.cc b/libstdc++-v3/testsuite/experimental/string_view/operations/compare/char/1.cc
index 565f2b1..e4d733f 100644
--- a/libstdc++-v3/testsuite/experimental/string_view/operations/compare/char/1.cc
+++ b/libstdc++-v3/testsuite/experimental/string_view/operations/compare/char/1.cc
@@ -82,8 +82,8 @@ test01()
   test_value(strncmp(str_1.data(), str_0.data(), 6), z);
   test_value(strncmp(str_1.data(), str_0.data(), 14), lt);
   test_value(memcmp(str_1.data(), str_0.data(), 6), z);
-  test_value(memcmp(str_1.data(), str_0.data(), 14), lt);
-  test_value(memcmp("costa marbella", "costa rica", 14), lt);
+  test_value(memcmp(str_1.data(), str_0.data(), 10), lt);
+  test_value(memcmp("costa marbella", "costa rica", 10), lt);
 
   // int compare(const basic_string_view& str) const;
   test_value(str_0.compare(str_1), gt); //because r>m
diff --git a/libstdc++-v3/testsuite/util/testsuite_character.cc b/libstdc++-v3/testsuite/util/testsuite_character.cc
index 7e6d7a5..e4fea0e 100644
--- a/libstdc++-v3/testsuite/util/testsuite_character.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_character.cc
@@ -154,11 +154,9 @@ namespace std
 	  value_type v = __num_base::_S_atoms_out[i];
 	  _M_data->_M_atoms_out[i].value = v;
 	}
-      _M_data->_M_atoms_out[__num_base::_S_oend] = pod_ushort();
 
       for (size_t j = 0; j < __num_base::_S_iend; ++j)
 	_M_data->_M_atoms_in[j].value = value_type(__num_base::_S_atoms_in[j]);
-      _M_data->_M_atoms_in[__num_base::_S_iend] = pod_ushort();
 
       // "true"
       pod_ushort* __truename = new pod_ushort[4 + 1];

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]