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 "thread_utils.h"
28 #include "test_utils.h"
29 #include "my_stacktrace.h"
30 #include "m_string.h"
31 #include "hash_filo.h"
32
33 namespace segfault_unittest {
34
35 using my_testing::Server_initializer;
36 using my_testing::Mock_error_handler;
37
38 class FatalSignalDeathTest : public ::testing::Test
39 {
40 protected:
SetUp()41 virtual void SetUp()
42 {
43 ::testing::FLAGS_gtest_death_test_style = "threadsafe";
44 initializer.SetUp();
45 }
TearDown()46 virtual void TearDown() { initializer.TearDown(); }
47
48 Server_initializer initializer;
49 };
50
51
TEST_F(FatalSignalDeathTest,Abort)52 TEST_F(FatalSignalDeathTest, Abort)
53 {
54 #if defined(_WIN32)
55 MY_EXPECT_DEATH_IF_SUPPORTED(abort(), ".* UTC - mysqld got exception.*");
56 #else
57 MY_EXPECT_DEATH_IF_SUPPORTED(abort(), ".* UTC - mysqld got signal 6.*");
58 #endif
59 }
60
61
TEST_F(FatalSignalDeathTest,Segfault)62 TEST_F(FatalSignalDeathTest, Segfault)
63 {
64 int *pint= NULL;
65 #if defined(_WIN32)
66 /*
67 After upgrading from gtest 1.5 to 1.6 this segfault is no longer
68 caught by handle_fatal_signal(). We get an empty error message from the
69 gtest library instead.
70 */
71 MY_EXPECT_DEATH_IF_SUPPORTED(*pint= 42, "");
72 #else
73 /*
74 On most platforms we get SIGSEGV == 11, but SIGBUS == 10 is also possible.
75 And on Mac OsX we can get SIGILL == 4 (but only in optmized mode).
76 */
77 MY_EXPECT_DEATH_IF_SUPPORTED(*pint= 42, ".* UTC - mysqld got signal .*");
78 #endif
79 }
80
81
82 // A simple helper function to determine array size.
83 template <class T, int size>
array_size(const T (&)[size])84 int array_size(const T (&)[size])
85 {
86 return size;
87 }
88
89
90 // Verifies that my_safe_utoa behaves like sprintf(_, "%llu", _)
TEST(PrintUtilities,Utoa)91 TEST(PrintUtilities, Utoa)
92 {
93 char buff[22];
94 ulonglong intarr[]= { 0, 1, 8, 12, 1234, 88888, ULONG_MAX, ULLONG_MAX };
95 char sprintbuff[22];
96 for (int ix= 0; ix < array_size(intarr); ++ix)
97 {
98 char *my_res;
99 sprintf(sprintbuff, "%llu", intarr[ix]);
100 my_res= my_safe_utoa(10, intarr[ix], &buff[sizeof(buff)-1]);
101 EXPECT_STREQ(sprintbuff, my_res);
102
103 if (intarr[ix] <= ULONG_MAX)
104 {
105 sprintf(sprintbuff, "%lu", (ulong) intarr[ix]);
106 my_res= my_safe_utoa(10, (ulong) intarr[ix], &buff[sizeof(buff)-1]);
107 EXPECT_STREQ(sprintbuff, my_res);
108 }
109 }
110 }
111
112
113 // Verifies that my_safe_itoa behaves like sprintf(_, "%lld", _)
TEST(PrintUtilities,Itoa)114 TEST(PrintUtilities, Itoa)
115 {
116 char buff[22];
117 char sprintbuff[22];
118 longlong intarr[]= { 0, 1, 8, 12, 1234, 88888, LONG_MAX, LLONG_MAX };
119
120 for (int ix= 0; ix < array_size(intarr); ++ix)
121 {
122 char *my_res;
123 sprintf(sprintbuff, "%lld", intarr[ix]);
124 my_res= my_safe_itoa(10, intarr[ix], &buff[sizeof(buff)-1]);
125 EXPECT_STREQ(sprintbuff, my_res);
126
127 ll2str(intarr[ix], buff, 10, 0);
128 EXPECT_STREQ(sprintbuff, buff);
129
130 sprintf(sprintbuff, "%lld", -intarr[ix]);
131 my_res= my_safe_itoa(10, -intarr[ix], &buff[sizeof(buff)-1]);
132 EXPECT_STREQ(sprintbuff, my_res);
133
134 // This one fails ....
135 // ll2str(-intarr[ix], buff, 10, 0);
136 // EXPECT_STREQ(sprintbuff, buff)
137 // << "failed for " << -intarr[ix];
138
139 sprintf(sprintbuff, "%llx", intarr[ix]);
140 my_res= my_safe_itoa(16, intarr[ix], &buff[sizeof(buff)-1]);
141 EXPECT_STREQ(sprintbuff, my_res);
142
143 ll2str(intarr[ix], buff, 16, 0);
144 EXPECT_STREQ(sprintbuff, buff);
145
146 sprintf(sprintbuff, "%llx", -intarr[ix]);
147 my_res= my_safe_itoa(16, -intarr[ix], &buff[sizeof(buff)-1]);
148 EXPECT_STREQ(sprintbuff, my_res)
149 << "failed for " << -intarr[ix];
150
151 ll2str(-intarr[ix], buff, 16, 0);
152 EXPECT_STREQ(sprintbuff, buff);
153 }
154 }
155
156
157 // Various tests for my_safe_snprintf.
TEST(PrintUtilities,Printf)158 TEST(PrintUtilities, Printf)
159 {
160 char buff[512];
161 char sprintfbuff[512];
162 const char *null_str= NULL;
163
164 my_safe_snprintf(buff, sizeof(buff), "hello");
165 EXPECT_STREQ("hello", buff);
166
167 my_safe_snprintf(buff, sizeof(buff), "hello %s hello", "hello");
168 EXPECT_STREQ("hello hello hello", buff);
169 my_safe_snprintf(buff, sizeof(buff), "hello %s hello", null_str);
170 EXPECT_STREQ("hello (null) hello", buff);
171
172 my_safe_snprintf(buff, sizeof(buff), "hello %d hello", 42);
173 EXPECT_STREQ("hello 42 hello", buff);
174 my_safe_snprintf(buff, sizeof(buff), "hello %i hello", 42);
175 EXPECT_STREQ("hello 42 hello", buff);
176 my_safe_snprintf(buff, sizeof(buff), "hello %u hello", (unsigned) 42);
177 EXPECT_STREQ("hello 42 hello", buff);
178
179 my_safe_snprintf(buff, sizeof(buff), "hello %llu hello", ULLONG_MAX);
180 sprintf(sprintfbuff, "hello %llu hello", ULLONG_MAX);
181 EXPECT_STREQ(sprintfbuff, buff);
182
183 my_safe_snprintf(buff, sizeof(buff), "hello %x hello", 42);
184 EXPECT_STREQ("hello 2a hello", buff);
185
186 my_safe_snprintf(buff, sizeof(buff), "hello %x hello", -42);
187 sprintf(sprintfbuff, "hello %x hello", -42);
188 EXPECT_STREQ("hello ffffffd6 hello", buff);
189 EXPECT_STREQ(sprintfbuff, buff);
190
191 my_safe_snprintf(buff, sizeof(buff), "hello %llx hello", (longlong) -42);
192 sprintf(sprintfbuff, "hello %llx hello", (longlong) -42);
193 EXPECT_STREQ("hello ffffffffffffffd6 hello", buff);
194 EXPECT_STREQ(sprintfbuff, buff);
195
196 void *p= this;
197 my_safe_snprintf(buff, sizeof(buff), "hello 0x%p hello", p);
198 my_snprintf(sprintfbuff, sizeof(sprintfbuff), "hello %p hello", p);
199 EXPECT_STREQ(sprintfbuff, buff) << "my_safe_snprintf:" << buff;
200 }
201
202
203 // After the fix for Bug#14689561, this is no longer a death test.
TEST(HashFiloTest,TestHashFiloZeroSize)204 TEST(HashFiloTest, TestHashFiloZeroSize)
205 {
206 hash_filo *t_cache;
207 t_cache= new hash_filo(PSI_NOT_INSTRUMENTED,
208 5, 0, 0,
209 (my_hash_get_key) NULL,
210 (my_hash_free_key) NULL,
211 NULL);
212 t_cache->clear();
213 t_cache->resize(0);
214 hash_filo_element entry;
215 // After resize (to zero) it tries to dereference last_link which is NULL.
216 t_cache->add(&entry);
217 delete t_cache;
218 }
219
220 }
221