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