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