Branch data Line data Source code
1 : : #include "sute.h"
2 : :
3 : : /**
4 : : * @brief Compile a PCRE2 pattern for match_regexp() unit tests
5 : : *
6 : : * @param[in] pattern_text Pattern text to compile
7 : : * @param[in] options PCRE2 compile options
8 : : * @return Compiled pattern or NULL on compilation failure
9 : : */
10 : 7 : static pcre2_code *compile_test_pattern(
11 : : const char *pattern_text,
12 : : uint32_t options)
13 : : {
14 : 7 : int error_code = 0;
15 : 7 : PCRE2_SIZE error_offset = 0;
16 : :
17 : 7 : return pcre2_compile(
18 : : (const unsigned char *)pattern_text,
19 : : strlen(pattern_text),
20 : : options,
21 : : &error_code,
22 : : &error_offset,
23 : : NULL);
24 : : }
25 : :
26 : : static REGEXP noisy_null_relative_path_response = MATCH;
27 : : static REGEXP noisy_damaged_path_response = MATCH;
28 : : static REGEXP noisy_invalid_utf8_path_response = MATCH;
29 : :
30 : : /**
31 : : * @brief Capture the NULL relative-path negative case
32 : : *
33 : : * @return SUCCESS when the negative call was exercised
34 : : */
35 : 1 : static Return capture_noisy_null_relative_path_case(void)
36 : : {
37 : 1 : INITTEST;
38 : :
39 : 1 : pcre2_code *compiled_pattern = compile_test_pattern(".",0);
40 : :
41 : 1 : ASSERT(compiled_pattern != NULL);
42 : 1 : noisy_null_relative_path_response = match_regexp(compiled_pattern,NULL);
43 : :
44 : 1 : pcre2_code_free(compiled_pattern);
45 : :
46 : 1 : deliver(status);
47 : : }
48 : :
49 : : /**
50 : : * @brief Capture the damaged relative-path descriptor negative case
51 : : *
52 : : * @return SUCCESS when the negative call was exercised
53 : : */
54 : 1 : static Return capture_noisy_damaged_path_case(void)
55 : : {
56 : 1 : INITTEST;
57 : :
58 : 1 : memory damaged_path = {
59 : : .single_element_size = sizeof(char),
60 : : .actually_allocated_bytes = sizeof(char),
61 : : .length = 1,
62 : : .string_length = 0,
63 : : .is_string = true,
64 : : .data = NULL
65 : : };
66 : 1 : pcre2_code *compiled_pattern = compile_test_pattern(".",0);
67 : :
68 : 1 : ASSERT(compiled_pattern != NULL);
69 : 1 : noisy_damaged_path_response = match_regexp(compiled_pattern,&damaged_path);
70 : :
71 : 1 : pcre2_code_free(compiled_pattern);
72 : :
73 : 1 : deliver(status);
74 : : }
75 : :
76 : : /**
77 : : * @brief Capture the invalid UTF-8 PCRE2 runtime error case
78 : : *
79 : : * @return SUCCESS when the negative call was exercised
80 : : */
81 : 1 : static Return capture_noisy_invalid_utf8_path_case(void)
82 : : {
83 : 1 : INITTEST;
84 : :
85 : : static const char invalid_utf8_subject[] = {
86 : : (char)0xC3,'(',0
87 : : };
88 : 1 : m_create(char,relative_path,MEMORY_STRING);
89 : 1 : pcre2_code *compiled_pattern = compile_test_pattern(".",PCRE2_UTF);
90 : :
91 : 1 : ASSERT(compiled_pattern != NULL);
92 : 1 : ASSERT(SUCCESS == m_copy_string(relative_path,sizeof(invalid_utf8_subject),invalid_utf8_subject));
93 : 1 : noisy_invalid_utf8_path_response = match_regexp(compiled_pattern,relative_path);
94 : :
95 : 1 : pcre2_code_free(compiled_pattern);
96 : 1 : call(m_del(relative_path));
97 : :
98 : 1 : deliver(status);
99 : : }
100 : :
101 : : /**
102 : : * @brief match_regexp() should report MATCH for a matching relative path
103 : : */
104 : 1 : static Return test0006_1(void)
105 : : {
106 : 1 : INITTEST;
107 : :
108 : 1 : m_create(char,relative_path,MEMORY_STRING);
109 : 1 : pcre2_code *compiled_pattern = compile_test_pattern("^src/.*\\.c$",0);
110 : :
111 : 1 : ASSERT(compiled_pattern != NULL);
112 : 1 : ASSERT(SUCCESS == m_copy_string(relative_path,"src/match_regexp.c"));
113 : 1 : ASSERT(MATCH == match_regexp(compiled_pattern,relative_path));
114 : :
115 : 1 : pcre2_code_free(compiled_pattern);
116 : 1 : call(m_del(relative_path));
117 : :
118 : 1 : RETURN_STATUS;
119 : : }
120 : :
121 : : /**
122 : : * @brief match_regexp() should report NOT_MATCH for a non-matching relative path
123 : : */
124 : 1 : static Return test0006_2(void)
125 : : {
126 : 1 : INITTEST;
127 : :
128 : 1 : m_create(char,relative_path,MEMORY_STRING);
129 : 1 : pcre2_code *compiled_pattern = compile_test_pattern("^tests/",0);
130 : :
131 : 1 : ASSERT(compiled_pattern != NULL);
132 : 1 : ASSERT(SUCCESS == m_copy_string(relative_path,"src/match_regexp.c"));
133 : 1 : ASSERT(NOT_MATCH == match_regexp(compiled_pattern,relative_path));
134 : :
135 : 1 : pcre2_code_free(compiled_pattern);
136 : 1 : call(m_del(relative_path));
137 : :
138 : 1 : RETURN_STATUS;
139 : : }
140 : :
141 : : /**
142 : : * @brief match_regexp() should allow an empty subject to match a pattern for an empty string
143 : : */
144 : 1 : static Return test0006_3(void)
145 : : {
146 : 1 : INITTEST;
147 : :
148 : 1 : m_create(char,relative_path,MEMORY_STRING);
149 : 1 : pcre2_code *compiled_pattern = compile_test_pattern("^$",0);
150 : :
151 : 1 : ASSERT(compiled_pattern != NULL);
152 : 1 : ASSERT(MATCH == match_regexp(compiled_pattern,relative_path));
153 : :
154 : 1 : pcre2_code_free(compiled_pattern);
155 : 1 : call(m_del(relative_path));
156 : :
157 : 1 : RETURN_STATUS;
158 : : }
159 : :
160 : : /**
161 : : * @brief match_regexp() should allow an empty subject to fail normally
162 : : */
163 : 1 : static Return test0006_4(void)
164 : : {
165 : 1 : INITTEST;
166 : :
167 : 1 : m_create(char,relative_path,MEMORY_STRING);
168 : 1 : pcre2_code *compiled_pattern = compile_test_pattern(".+",0);
169 : :
170 : 1 : ASSERT(compiled_pattern != NULL);
171 : 1 : ASSERT(NOT_MATCH == match_regexp(compiled_pattern,relative_path));
172 : :
173 : 1 : pcre2_code_free(compiled_pattern);
174 : 1 : call(m_del(relative_path));
175 : :
176 : 1 : RETURN_STATUS;
177 : : }
178 : :
179 : : /**
180 : : * @brief match_regexp() should reject a missing compiled pattern
181 : : */
182 : 1 : static Return test0006_5(void)
183 : : {
184 : 1 : INITTEST;
185 : :
186 : 1 : m_create(char,relative_path,MEMORY_STRING);
187 : :
188 : 1 : ASSERT(SUCCESS == m_copy_string(relative_path,"src/match_regexp.c"));
189 : 1 : ASSERT(REGEXP_ERROR == match_regexp(NULL,relative_path));
190 : :
191 : 1 : call(m_del(relative_path));
192 : :
193 : 1 : RETURN_STATUS;
194 : : }
195 : :
196 : : /**
197 : : * @brief match_regexp() should reject a missing relative path descriptor
198 : : */
199 : 1 : static Return test0006_6(void)
200 : : {
201 : 1 : INITTEST;
202 : :
203 : 1 : noisy_null_relative_path_response = MATCH;
204 : :
205 : 1 : ASSERT(SUCCESS == match_function_output(
206 : : NULL,
207 : : NULL,
208 : : capture_noisy_null_relative_path_case));
209 : 1 : ASSERT(REGEXP_ERROR == noisy_null_relative_path_response);
210 : :
211 : 1 : RETURN_STATUS;
212 : : }
213 : :
214 : : /**
215 : : * @brief match_regexp() should report REGEXP_ERROR for a damaged path descriptor
216 : : */
217 : 1 : static Return test0006_7(void)
218 : : {
219 : 1 : INITTEST;
220 : :
221 : : static const char expected_stderr_pattern[] =
222 : : "\\A"
223 : : "ERROR: [^\\n]*Memory management; Descriptor has non-zero length with NULL data pointer[^\\n]*\n"
224 : : "\\Z";
225 : :
226 : 1 : noisy_damaged_path_response = MATCH;
227 : :
228 : 1 : ASSERT(SUCCESS == match_function_output(
229 : : NULL,
230 : : expected_stderr_pattern,
231 : : capture_noisy_damaged_path_case));
232 : 1 : ASSERT(REGEXP_ERROR == noisy_damaged_path_response);
233 : :
234 : 1 : RETURN_STATUS;
235 : : }
236 : :
237 : : /**
238 : : * @brief match_regexp() should report REGEXP_ERROR for a PCRE2 runtime match error
239 : : */
240 : 1 : static Return test0006_8(void)
241 : : {
242 : 1 : INITTEST;
243 : :
244 : : static const char expected_stdout_pattern[] =
245 : : "\\A"
246 : : "ERROR: PCRE2 match error -8: UTF-8 error: byte 2 top bits not 0x80 for path: \\\\xC3\\(\n"
247 : : "\\Z";
248 : :
249 : 1 : noisy_invalid_utf8_path_response = MATCH;
250 : :
251 : 1 : ASSERT(SUCCESS == match_function_output(
252 : : expected_stdout_pattern,
253 : : NULL,
254 : : capture_noisy_invalid_utf8_path_case));
255 : 1 : ASSERT(REGEXP_ERROR == noisy_invalid_utf8_path_response);
256 : :
257 : 1 : RETURN_STATUS;
258 : : }
259 : :
260 : : /**
261 : : * @brief Run unit tests for match_regexp()
262 : : */
263 : 1 : Return test0006(void)
264 : : {
265 : 1 : INITTEST;
266 : :
267 : 1 : TEST(test0006_1,"match_regexp(): matching path");
268 : 1 : TEST(test0006_2,"match_regexp(): non-matching path");
269 : 1 : TEST(test0006_3,"match_regexp(): empty subject can match");
270 : 1 : TEST(test0006_4,"match_regexp(): empty subject can fail normally");
271 : 1 : TEST(test0006_5,"match_regexp(): NULL compiled pattern");
272 : 1 : TEST(test0006_6,"match_regexp(): NULL relative path");
273 : 1 : TEST(test0006_7,"match_regexp(): damaged relative path descriptor");
274 : 1 : TEST(test0006_8,"match_regexp(): PCRE2 runtime match error");
275 : :
276 : 1 : RETURN_STATUS;
277 : : }
|