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