1 /* Copyright (c) 2011, 2021, Oracle and/or its affiliates.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
22 
23 // Always include (the generated) my_config.h, to get correct platform defines.
24 #include "my_config.h"
25 #include <gtest/gtest.h>
26 
27 #include "test_utils.h"
28 #include "my_stacktrace.h"
29 #include "m_string.h"
30 #include "hash_filo.h"
31 
32 namespace segfault_unittest {
33 
34 using my_testing::Server_initializer;
35 using my_testing::Mock_error_handler;
36 
37 class FatalSignalDeathTest : public ::testing::Test
38 {
39 protected:
SetUp()40   virtual void SetUp()
41   {
42     ::testing::FLAGS_gtest_death_test_style = "threadsafe";
43     initializer.SetUp();
44   }
TearDown()45   virtual void TearDown() { initializer.TearDown(); }
46 
47   Server_initializer initializer;
48 };
49 
50 
TEST_F(FatalSignalDeathTest,Abort)51 TEST_F(FatalSignalDeathTest, Abort)
52 {
53 #if defined(_WIN32)
54   EXPECT_DEATH_IF_SUPPORTED(abort(), ".* UTC - mysqld got exception.*");
55 #else
56   EXPECT_DEATH_IF_SUPPORTED(abort(), ".* UTC - mysqld got signal 6.*");
57 #endif
58 }
59 
60 
TEST_F(FatalSignalDeathTest,Segfault)61 TEST_F(FatalSignalDeathTest, Segfault)
62 {
63 #if defined(_WIN32)
64   int *pint= NULL;
65   /*
66    After upgrading from gtest 1.5 to 1.6 this segfault is no longer
67    caught by handle_fatal_signal(). We get an empty error message from the
68    gtest library instead.
69   */
70   EXPECT_DEATH_IF_SUPPORTED(*pint= 42, "");
71 #elif defined(HAVE_ASAN)
72   /* gcc 4.8.1 with '-fsanitize=address -O1' */
73   /* Newer versions of ASAN give other error message, disable it */
74   // EXPECT_DEATH_IF_SUPPORTED(*pint= 42, ".*ASAN:SIGSEGV.*");
75 #else
76   int *pint= NULL;
77   /*
78    On most platforms we get SIGSEGV == 11, but SIGBUS == 10 is also possible.
79    And on Mac OsX we can get SIGILL == 4 (but only in optmized mode).
80   */
81   EXPECT_DEATH_IF_SUPPORTED(*pint= 42, ".* UTC - mysqld got signal .*");
82 #endif
83 }
84 
85 
86 // A simple helper function to determine array size.
87 template <class T, int size>
array_size(const T (&)[size])88 int array_size(const T (&)[size])
89 {
90   return size;
91 }
92 
93 
94 // Verifies that my_safe_utoa behaves like sprintf(_, "%llu", _)
TEST(PrintUtilities,Utoa)95 TEST(PrintUtilities, Utoa)
96 {
97   char buff[22];
98   ulonglong intarr[]= { 0, 1, 8, 12, 1234, 88888, ULONG_MAX, ULLONG_MAX };
99   char sprintbuff[22];
100   for (int ix= 0; ix < array_size(intarr); ++ix)
101   {
102     char *my_res;
103     sprintf(sprintbuff, "%llu", intarr[ix]);
104     my_res= my_safe_utoa(10, intarr[ix], &buff[sizeof(buff)-1]);
105     EXPECT_STREQ(sprintbuff, my_res);
106 
107     if (intarr[ix] <= ULONG_MAX)
108     {
109       sprintf(sprintbuff, "%lu", (ulong) intarr[ix]);
110       my_res= my_safe_utoa(10, (ulong) intarr[ix], &buff[sizeof(buff)-1]);
111       EXPECT_STREQ(sprintbuff, my_res);
112     }
113   }
114 }
115 
116 
117 // Verifies that my_safe_itoa behaves like sprintf(_, "%lld", _)
TEST(PrintUtilities,Itoa)118 TEST(PrintUtilities, Itoa)
119 {
120   char buff[22];
121   char sprintbuff[22];
122   longlong intarr[]= { 0, 1, 8, 12, 1234, 88888, LONG_MAX, LLONG_MAX };
123 
124   for (int ix= 0; ix < array_size(intarr); ++ix)
125   {
126     char *my_res;
127     sprintf(sprintbuff, "%lld", intarr[ix]);
128     my_res= my_safe_itoa(10, intarr[ix], &buff[sizeof(buff)-1]);
129     EXPECT_STREQ(sprintbuff, my_res);
130 
131     ll2str(intarr[ix], buff, 10, 0);
132     EXPECT_STREQ(sprintbuff, buff);
133 
134     sprintf(sprintbuff, "%lld", -intarr[ix]);
135     my_res= my_safe_itoa(10, -intarr[ix], &buff[sizeof(buff)-1]);
136     EXPECT_STREQ(sprintbuff, my_res);
137 
138     // This one fails ....
139     // ll2str(-intarr[ix], buff, 10, 0);
140     // EXPECT_STREQ(sprintbuff, buff)
141     //  << "failed for " << -intarr[ix];
142 
143     sprintf(sprintbuff, "%llx", intarr[ix]);
144     my_res= my_safe_itoa(16, intarr[ix], &buff[sizeof(buff)-1]);
145     EXPECT_STREQ(sprintbuff, my_res);
146 
147     ll2str(intarr[ix], buff, 16, 0);
148     EXPECT_STREQ(sprintbuff, buff);
149 
150     sprintf(sprintbuff, "%llx", -intarr[ix]);
151     my_res= my_safe_itoa(16, -intarr[ix], &buff[sizeof(buff)-1]);
152     EXPECT_STREQ(sprintbuff, my_res)
153       << "failed for " << -intarr[ix];
154 
155     ll2str(-intarr[ix], buff, 16, 0);
156     EXPECT_STREQ(sprintbuff, buff);
157   }
158 }
159 
160 
161 // Various tests for my_safe_snprintf.
TEST(PrintUtilities,Printf)162 TEST(PrintUtilities, Printf)
163 {
164   char buff[512];
165   char sprintfbuff[512];
166   const char *null_str= NULL;
167 
168   my_safe_snprintf(buff, sizeof(buff), "hello");
169   EXPECT_STREQ("hello", buff);
170 
171   my_safe_snprintf(buff, sizeof(buff), "hello %s hello", "hello");
172   EXPECT_STREQ("hello hello hello", buff);
173   my_safe_snprintf(buff, sizeof(buff), "hello %s hello", null_str);
174   EXPECT_STREQ("hello (null) hello", buff);
175 
176   my_safe_snprintf(buff, sizeof(buff), "hello %d hello", 42);
177   EXPECT_STREQ("hello 42 hello", buff);
178   my_safe_snprintf(buff, sizeof(buff), "hello %i hello", 42);
179   EXPECT_STREQ("hello 42 hello", buff);
180   my_safe_snprintf(buff, sizeof(buff), "hello %u hello", (unsigned) 42);
181   EXPECT_STREQ("hello 42 hello", buff);
182 
183   my_safe_snprintf(buff, sizeof(buff), "hello %llu hello", ULLONG_MAX);
184   sprintf(sprintfbuff, "hello %llu hello", ULLONG_MAX);
185   EXPECT_STREQ(sprintfbuff, buff);
186 
187   my_safe_snprintf(buff, sizeof(buff), "hello %x hello", 42);
188   EXPECT_STREQ("hello 2a hello", buff);
189 
190   my_safe_snprintf(buff, sizeof(buff), "hello %x hello", -42);
191   sprintf(sprintfbuff, "hello %x hello", -42);
192   EXPECT_STREQ("hello ffffffd6 hello", buff);
193   EXPECT_STREQ(sprintfbuff, buff);
194 
195   my_safe_snprintf(buff, sizeof(buff), "hello %llx hello", (longlong) -42);
196   sprintf(sprintfbuff, "hello %llx hello", (longlong) -42);
197   EXPECT_STREQ("hello ffffffffffffffd6 hello", buff);
198   EXPECT_STREQ(sprintfbuff, buff);
199 
200   void *p= this;
201   my_safe_snprintf(buff, sizeof(buff), "hello 0x%p hello", p);
202   my_snprintf(sprintfbuff, sizeof(sprintfbuff), "hello %p hello", p);
203   EXPECT_STREQ(sprintfbuff, buff) << "my_safe_snprintf:" << buff;
204 }
205 
206 
207 // After the fix for Bug#14689561, this is no longer a death test.
TEST(HashFiloTest,TestHashFiloZeroSize)208 TEST(HashFiloTest, TestHashFiloZeroSize)
209 {
210   hash_filo *t_cache;
211   t_cache= new hash_filo(PSI_NOT_INSTRUMENTED,
212                          5, 0, 0,
213                          (my_hash_get_key) NULL,
214                          (my_hash_free_key) NULL,
215                          NULL);
216   t_cache->clear();
217   t_cache->resize(0);
218   hash_filo_element entry;
219   // After resize (to zero) it tries to dereference last_link which is NULL.
220   t_cache->add(&entry);
221   delete t_cache;
222 }
223 
224 }
225