1 /* Copyright (c) 2010, 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 Street, Fifth Floor, Boston, MA 02110-1301, USA */
22
23 // First include (the generated) my_config.h, to get correct platform defines.
24 #include "my_config.h"
25 #include <gtest/gtest.h>
26
27 #include "my_regex.h"
28
29 /*
30 Thist is just a *very* basic test that things compile/link and execute.
31 The test data is taken from the first few lines in regex/tests.
32 For a full test suite, see regex/main.c which parses test input
33 and tests expected sucess/failure with basic/extended regexps etc. etc.
34 */
35
36 namespace my_regex_unittest {
37
38 const int NSUBS= 10;
39
40 class RegexTest : public ::testing::Test
41 {
42 protected:
RegexTest()43 RegexTest()
44 {
45 memset(&re, 0, sizeof(re));
46 }
TearDownTestCase()47 static void TearDownTestCase()
48 {
49 my_regex_end();
50 }
51
52 my_regmatch_t subs[NSUBS];
53 my_regex_t re;
54 };
55
56 struct Re_test_data
57 {
58 const char* pattern; // Column 1 in regex/tests.
59 const int cflags; // Column 2 in regex/tests.
60 const char* input; // Column 3 in regex/tests.
61 };
62
63 Re_test_data basic_data[]=
64 {
65 { "a", MY_REG_BASIC, "a" },
66 { "abc", MY_REG_BASIC, "abc" },
67 { "abc|de", MY_REG_EXTENDED, "abc" },
68 { "a|b|c", MY_REG_EXTENDED, "abc" },
69 { NULL, 0, NULL }
70 };
71
TEST_F(RegexTest,BasicTest)72 TEST_F(RegexTest, BasicTest)
73 {
74 for (int ix=0; basic_data[ix].pattern; ++ix)
75 {
76 EXPECT_EQ(0, my_regcomp(&re,
77 basic_data[ix].pattern,
78 basic_data[ix].cflags,
79 &my_charset_latin1));
80
81 int err= my_regexec(&re, basic_data[ix].input, NSUBS, subs, 0);
82 EXPECT_EQ(0, err)
83 << "my_regexec returned " << err
84 << " for pattern '" << basic_data[ix].pattern << "'"
85 << " with input '" << basic_data[ix].input << "'";
86 my_regfree(&re);
87 }
88 }
89
90 /*
91 Bug#20642505: HENRY SPENCER REGULAR EXPRESSIONS (REGEX) LIBRARY
92
93 We have our own variant of the regex code that understands MySQL charsets.
94 This test is hear to make sure that we never checkpoint or cherrypick from
95 the upstream and end up with a version that isn't patched against a
96 potential overflow.
97 */
TEST_F(RegexTest,Bug20642505)98 TEST_F(RegexTest, Bug20642505)
99 {
100 my_regex_t re;
101 char *pattern;
102 int err;
103 size_t len= 684 * 1024 * 1024;
104
105 /*
106 We're testing on 32-bit/32-bit only. We could test e.g. with
107 64-bit size_t, 32-bit long (for 64-bit Windows and such), but
108 then we'd have to allocate twice as much memory, and it's a
109 bit heavy as it is. (In 32/32, we exceed the size_t parameter
110 to malloc() as new_ssize exceeds UINT32 / 4, whereas in 64/32,
111 new_ssize would exceed LONG_MAX at UINT32 / 2. (64/32 verified
112 in debugger.)
113 */
114 if ((sizeof(size_t) > 4) || (sizeof(long) > 4))
115 return;
116
117 /* set up an empty C string as pattern as regcomp() will strlen() this */
118 pattern= (char *) malloc(len);
119 EXPECT_FALSE(pattern == NULL);
120 memset(pattern, (int) ' ', len);
121 pattern[len - 1]= '\0';
122
123 err= my_regcomp(&re, pattern, MY_REG_BASIC,
124 &my_charset_latin1);
125
126 my_regfree(&re);
127 free(pattern);
128
129 EXPECT_EQ(err, MY_REG_ESPACE)
130 << "my_regcomp returned " << err
131 << " instead of MY_REG_ESPACE (" << MY_REG_ESPACE << ")";
132 }
133
134 } // namespace
135