12
12
#include <string.h>
13
13
#include <stdlib.h>
14
14
#include <cmocka.h>
15
+ #include <limits.h>
15
16
#if !_WIN32
16
17
#include <unistd.h>
17
18
#endif
@@ -125,6 +126,42 @@ int setup(void **state)
125
126
return -1 ;
126
127
}
127
128
129
+ static char * generate_include (const char * text )
130
+ {
131
+ char * path = tempnam (NULL , "zone" );
132
+ if (path ) {
133
+ FILE * handle = fopen (path , "wbx" );
134
+ if (handle ) {
135
+ int result = fputs (text , handle );
136
+ (void )fclose (handle );
137
+ if (result != EOF )
138
+ return path ;
139
+ }
140
+ free (path );
141
+ }
142
+ return NULL ;
143
+ }
144
+
145
+ static int32_t parse (
146
+ const zone_options_t * options , const char * text , void * user_data )
147
+ {
148
+ zone_parser_t parser = { 0 };
149
+ zone_name_buffer_t name ;
150
+ zone_rdata_buffer_t rdata ;
151
+ zone_buffers_t buffers = { 1 , & name , & rdata };
152
+
153
+ int32_t code ;
154
+ size_t length = strlen (text );
155
+ char * string = malloc (length + 1 + ZONE_PADDING_SIZE );
156
+ assert_non_null (string );
157
+ memcpy (string , text , length );
158
+ string [length ] = '\0' ;
159
+
160
+ code = zone_parse_string (& parser , options , & buffers , string , length , user_data );
161
+ free (string );
162
+ return code ;
163
+ }
164
+
128
165
diagnostic_pop ()
129
166
130
167
static int32_t add_rr (
@@ -216,12 +253,12 @@ static int32_t no_such_file_accept(
216
253
217
254
static void no_such_file_log (
218
255
zone_parser_t * parser ,
219
- uint32_t category ,
256
+ uint32_t priority ,
220
257
const char * message ,
221
258
void * user_data )
222
259
{
223
260
(void )parser ;
224
- (void )category ;
261
+ (void )priority ;
225
262
if (!strstr (message , "no such file" ))
226
263
return ;
227
264
no_file_test_t * test = (no_file_test_t * )user_data ;
@@ -232,10 +269,6 @@ static void no_such_file_log(
232
269
void the_include_that_wasnt (void * * state )
233
270
{
234
271
// test $INCLUDE of nonexistent file is handled gracefully
235
- zone_parser_t parser = { 0 };
236
- zone_name_buffer_t name ;
237
- zone_rdata_buffer_t rdata ;
238
- zone_buffers_t buffers = { 1 , & name , & rdata };
239
272
zone_options_t options = { 0 };
240
273
no_file_test_t test = { 0 };
241
274
int32_t code ;
@@ -245,7 +278,7 @@ void the_include_that_wasnt(void **state)
245
278
options .origin .octets = origin ;
246
279
options .origin .length = sizeof (origin );
247
280
options .default_ttl = 3600 ;
248
- options .default_class = ZONE_IN ;
281
+ options .default_class = 1 ;
249
282
250
283
(void )state ;
251
284
@@ -256,16 +289,139 @@ void the_include_that_wasnt(void **state)
256
289
int length = snprintf (buffer , sizeof (buffer ), "$INCLUDE %s" , non_include );
257
290
assert_true (length >= 0 && (size_t )length < SIZE_MAX - (ZONE_PADDING_SIZE + 1 ));
258
291
259
- char * include = malloc ((size_t )length + 1 + ZONE_PADDING_SIZE );
292
+ char * include = malloc ((size_t )length + 1 );
260
293
assert_non_null (include );
261
294
(void )snprintf (include , (size_t )length + 1 , "$INCLUDE %s" , non_include );
262
295
263
- code = zone_parse_string (& parser , & options , & buffers , include , (size_t )length , & test );
296
+ code = parse (& options , include , & test );
297
+ free (include );
298
+ free (non_include );
264
299
assert_int_equal (code , ZONE_NOT_A_FILE );
265
300
assert_true (test .log_count == 1 );
266
301
assert_true (test .accept_count == 0 );
302
+ }
303
+
304
+ static int32_t in_too_deep_accept (
305
+ zone_parser_t * parser ,
306
+ const zone_name_t * owner ,
307
+ uint16_t type ,
308
+ uint16_t class ,
309
+ uint32_t ttl ,
310
+ uint16_t rdlength ,
311
+ const uint8_t * rdata ,
312
+ void * user_data )
313
+ {
314
+ (void )parser ;
315
+ (void )owner ;
316
+ (void )type ;
317
+ (void )class ;
318
+ (void )ttl ;
319
+ (void )rdlength ;
320
+ (void )rdata ;
321
+ (* (size_t * )user_data )++ ;
322
+ return 0 ;
323
+ }
324
+
325
+ static void in_too_deep_log (
326
+ zone_parser_t * parser ,
327
+ uint32_t priority ,
328
+ const char * message ,
329
+ void * user_data )
330
+ {
331
+ (void )parser ;
332
+ (void )priority ;
333
+
334
+ if (strstr (message , "nested too deeply" ))
335
+ * (size_t * )user_data |= 1u << 7 ;
336
+ }
337
+
338
+ /*!cmocka */
339
+ void in_too_deep (void * * state )
340
+ {
341
+ (void )state ;
342
+
343
+ int32_t code ;
344
+ size_t records ;
345
+ zone_options_t options = { 0 };
346
+
347
+ options .accept .callback = & in_too_deep_accept ;
348
+ options .log .callback = & in_too_deep_log ;
349
+ options .origin .octets = origin ;
350
+ options .origin .length = sizeof (origin );
351
+ options .default_ttl = 3600 ;
352
+ options .default_class = 1 ;
353
+ options .include_limit = 1 ;
354
+
355
+ #define INCLUDE "$INCLUDE %s\n"
356
+
357
+ char * deeper = generate_include ("foo. TXT \"bar\"" );
358
+ assert_non_null (deeper );
359
+ char buffer [16 ];
360
+ int length = snprintf (buffer , sizeof (buffer ), INCLUDE , deeper );
361
+ assert_true (length > 0 );
362
+ char * inception = malloc ((size_t )length + 1 );
363
+ assert_non_null (inception );
364
+ (void )snprintf (inception , (size_t )length + 1 , INCLUDE , deeper );
365
+ char * deep = generate_include (inception );
366
+ assert_non_null (deep );
367
+ free (inception );
368
+ length = snprintf (buffer , sizeof (buffer ), INCLUDE , deep );
369
+ assert_true (length > 0 );
370
+ inception = malloc ((size_t )length + 1 );
371
+ (void )snprintf (inception , (size_t )length + 1 , INCLUDE , deep );
372
+
373
+ #undef INCLUDE
374
+
375
+ records = 0 ;
376
+ code = parse (& options , inception , & records );
377
+ assert_int_equal (code , ZONE_SEMANTIC_ERROR );
378
+ assert_int_equal (records , (1u << 7 ));
379
+
380
+ options .include_limit = 0 ;
381
+ records = 0 ;
382
+ code = parse (& options , inception , & records );
383
+ assert_int_equal (code , ZONE_SUCCESS );
384
+ assert_int_equal (records , 1u );
385
+
386
+ free (inception );
387
+ free (deep );
388
+ free (deeper );
389
+ }
390
+
391
+ /*!cmocka */
392
+ void been_there_done_that (void * * state )
393
+ {
394
+ (void )state ;
395
+
396
+ zone_options_t options = { 0 };
397
+ options .accept .callback = & in_too_deep_accept ;
398
+ options .log .callback = & in_too_deep_log ;
399
+ options .origin .octets = origin ;
400
+ options .origin .length = sizeof (origin );
401
+ options .default_ttl = 3600 ;
402
+ options .default_class = 1 ;
403
+ options .include_limit = 1 ;
404
+
405
+ int32_t code ;
406
+ size_t count = 0 ;
407
+
408
+ char * path = generate_include (" " );
409
+ assert_non_null (path );
410
+ FILE * handle = fopen (path , "wb" );
411
+ assert_non_null (handle );
412
+ char dummy [16 ];
413
+ int length = snprintf (dummy , sizeof (dummy ), "$INCLUDE \"%s\"\n" , path );
414
+ assert_true (length > 0 && length < INT_MAX - ZONE_PADDING_SIZE );
415
+ char * include = malloc ((size_t )length + 1 + ZONE_PADDING_SIZE );
416
+ assert_non_null (include );
417
+ (void )snprintf (include , (size_t )length + 1 , "$INCLUDE \"%s\"\n" , path );
418
+ int result = fputs (include , handle );
419
+ assert_true (result >= 0 );
420
+ (void )fclose (handle );
421
+ free (path );
422
+ code = parse (& options , include , & count );
267
423
free (include );
268
- free ( non_include );
424
+ assert_int_equal ( code , ZONE_SEMANTIC_ERROR );
269
425
}
270
426
271
427
//
0 commit comments