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