@@ -715,11 +715,14 @@ void bad_origins(void **state)
715715
716716 static const char * no_origin = PAD ("$ORIGIN ; no origin" );
717717 static const char * extra_origin = PAD ("$ORIGIN a. b." );
718+ static const char * relative_origin = PAD ("$ORIGIN foo" );
718719
719720 code = parse (no_origin , & count );
720721 assert_int_equal (code , ZONE_SYNTAX_ERROR );
721722 code = parse (extra_origin , & count );
722723 assert_int_equal (code , ZONE_SYNTAX_ERROR );
724+ code = parse (relative_origin , & count );
725+ assert_int_equal (code , ZONE_SYNTAX_ERROR );
723726}
724727
725728/*!cmocka */
@@ -753,3 +756,256 @@ void bad_includes(void **state)
753756 free (include );
754757 assert_int_equal (code , ZONE_SYNTAX_ERROR );
755758}
759+
760+ static int32_t include_origin_callback (
761+ zone_parser_t * parser ,
762+ const zone_name_t * owner ,
763+ uint16_t type ,
764+ uint16_t class ,
765+ uint32_t ttl ,
766+ uint16_t rdlength ,
767+ const uint8_t * rdata ,
768+ void * user_data )
769+ {
770+ (void )parser ;
771+ (void )type ;
772+ (void )class ;
773+ (void )ttl ;
774+ (void )rdlength ;
775+ (void )rdata ;
776+ (void )user_data ;
777+
778+ static const uint8_t foobaz [] = { 3 , 'f' , 'o' , 'o' , 3 , 'b' , 'a' , 'z' , 0 };
779+
780+ assert (owner );
781+ if (owner -> length != 9 || memcmp (owner -> octets , foobaz , 9 ) != 0 )
782+ return ZONE_SEMANTIC_ERROR ;
783+
784+ return 0 ;
785+ }
786+
787+ /*!cmocka */
788+ void include_with_origin (void * * state )
789+ {
790+ (void )state ;
791+
792+ char * path = generate_include ("foo TXT bar" );
793+ assert_non_null (path );
794+ char dummy [32 ];
795+ int length = snprintf (dummy , sizeof (dummy ), "$INCLUDE \"%s\" baz." , path );
796+ assert_true (length > 0 && length < INT_MAX - ZONE_PADDING_SIZE );
797+ char * include = malloc ((size_t )length + 1 + ZONE_PADDING_SIZE );
798+ assert_non_null (include );
799+ (void )snprintf (include , (size_t )length + 1 , "$INCLUDE \"%s\" baz." , path );
800+
801+ zone_parser_t parser ;
802+ zone_name_buffer_t name ;
803+ zone_rdata_buffer_t rdata ;
804+ zone_buffers_t buffers = { 1 , & name , & rdata };
805+ zone_options_t options = { 0 };
806+ static const uint8_t origin [] = { 3 , 'b' , 'a' , 'r' , 0 };
807+
808+ options .accept .callback = & include_origin_callback ;
809+ options .origin .octets = origin ;
810+ options .origin .length = sizeof (origin );
811+ options .default_ttl = 3600 ;
812+ options .default_class = 1 ;
813+
814+ int32_t code = zone_parse_string (& parser , & options , & buffers , include , strlen (include ), NULL );
815+
816+ remove_include (path );
817+ free (path );
818+ free (include );
819+
820+ assert_int_equal (code , ZONE_SUCCESS );
821+ }
822+
823+ static int32_t no_origin_callback (
824+ zone_parser_t * parser ,
825+ const zone_name_t * owner ,
826+ uint16_t type ,
827+ uint16_t class ,
828+ uint32_t ttl ,
829+ uint16_t rdlength ,
830+ const uint8_t * rdata ,
831+ void * user_data )
832+ {
833+ (void )parser ;
834+ (void )type ;
835+ (void )class ;
836+ (void )ttl ;
837+ (void )rdlength ;
838+ (void )rdata ;
839+ (void )user_data ;
840+
841+ static const uint8_t foobar [] = { 3 , 'f' , 'o' , 'o' , 3 , 'b' , 'a' , 'r' , 0 };
842+
843+ assert (owner );
844+ if (owner -> length != 9 || memcmp (owner -> octets , foobar , 9 ) != 0 )
845+ return ZONE_SEMANTIC_ERROR ;
846+
847+ return 0 ;
848+ }
849+
850+ /*!cmocka */
851+ void include_without_origin (void * * state )
852+ {
853+ (void )state ;
854+
855+ char * path = generate_include ("foo TXT bar" );
856+ assert_non_null (path );
857+ char dummy [32 ];
858+ #define FMT "$INCLUDE \"%s\""
859+ int length = snprintf (dummy , sizeof (dummy ), "$INCLUDE \"%s\"" , path );
860+ assert_true (length > 0 && length < INT_MAX - ZONE_PADDING_SIZE );
861+ char * include = malloc ((size_t )length + 1 + ZONE_PADDING_SIZE );
862+ assert_non_null (include );
863+ (void )snprintf (include , (size_t )length + 1 , "$INCLUDE \"%s\"" , path );
864+ #undef FMT
865+
866+ zone_parser_t parser ;
867+ zone_name_buffer_t name ;
868+ zone_rdata_buffer_t rdata ;
869+ zone_buffers_t buffers = { 1 , & name , & rdata };
870+ zone_options_t options = { 0 };
871+ static const uint8_t origin [] = { 3 , 'b' , 'a' , 'r' , 0 };
872+
873+ options .accept .callback = & no_origin_callback ;
874+ options .origin .octets = origin ;
875+ options .origin .length = sizeof (origin );
876+ options .default_ttl = 3600 ;
877+ options .default_class = 1 ;
878+
879+ int32_t code = zone_parse_string (& parser , & options , & buffers , include , strlen (include ), NULL );
880+
881+ remove_include (path );
882+ free (path );
883+ free (include );
884+
885+ assert_int_equal (code , ZONE_SUCCESS );
886+ }
887+
888+ static int32_t reinstate_callback (
889+ zone_parser_t * parser ,
890+ const zone_name_t * owner ,
891+ uint16_t type ,
892+ uint16_t class ,
893+ uint32_t ttl ,
894+ uint16_t rdlength ,
895+ const uint8_t * rdata ,
896+ void * user_data )
897+ {
898+ size_t * count = (size_t * )user_data ;
899+
900+ static const uint8_t foobar [] = { 3 , 'f' , 'o' , 'o' , 3 , 'b' , 'a' , 'r' , 0 };
901+ static const uint8_t foobaz [] = { 3 , 'f' , 'o' , 'o' , 3 , 'b' , 'a' , 'z' , 0 };
902+
903+ (void )parser ;
904+ (void )type ;
905+ (void )class ;
906+ (void )ttl ;
907+ (void )rdlength ;
908+ (void )rdata ;
909+
910+ switch (* count ) {
911+ case 0 :
912+ if (owner -> length != 9 || memcmp (owner -> octets , foobar , 9 ) != 0 )
913+ return ZONE_SYNTAX_ERROR ;
914+ break ;
915+ case 1 : // include
916+ if (owner -> length != 9 || memcmp (owner -> octets , foobaz , 9 ) != 0 )
917+ return ZONE_SYNTAX_ERROR ;
918+ break ;
919+ case 2 :
920+ if (owner -> length != 9 || memcmp (owner -> octets , foobar , 9 ) != 0 )
921+ return ZONE_SYNTAX_ERROR ;
922+ break ;
923+ }
924+
925+ (* count )++ ;
926+ return 0 ;
927+ }
928+
929+ /*!cmocka */
930+ void owner_is_reinstated (void * * state )
931+ {
932+ // check closing of include reinstates owner
933+
934+ (void )state ;
935+ char * path = generate_include ("foo.baz. TXT foobar" );
936+ assert_non_null (path );
937+ char dummy [64 ];
938+ #define FMT \
939+ "foo.bar. TXT foobar\n" \
940+ "$INCLUDE \"%s\" baz.\n" \
941+ " TXT foobar"
942+ int length = snprintf (dummy , sizeof (dummy ), FMT , path );
943+ assert_true (length > 0 && length < INT_MAX - ZONE_PADDING_SIZE );
944+ char * include = malloc ((size_t )length + 1 + ZONE_PADDING_SIZE );
945+ assert_non_null (include );
946+ (void )snprintf (include , (size_t )length + 1 , FMT , path );
947+ #undef FMT
948+
949+ size_t count = 0 ;
950+ zone_parser_t parser ;
951+ zone_name_buffer_t name ;
952+ zone_rdata_buffer_t rdata ;
953+ zone_buffers_t buffers = { 1 , & name , & rdata };
954+ zone_options_t options = { 0 };
955+ static const uint8_t origin [] = { 3 , 'b' , 'a' , 'r' , 0 };
956+
957+ options .accept .callback = & reinstate_callback ;
958+ options .origin .octets = origin ;
959+ options .origin .length = sizeof (origin );
960+ options .default_ttl = 3600 ;
961+ options .default_class = 1 ;
962+
963+ int32_t code = zone_parse_string (& parser , & options , & buffers , include , strlen (include ), & count );
964+ remove_include (path );
965+ free (path );
966+ free (include );
967+ assert_int_equal (code , ZONE_SUCCESS );
968+ assert_true (count == 3 );
969+ }
970+
971+ /*!cmocka */
972+ void origin_is_reinstated (void * * state )
973+ {
974+ // check closing of include reinstates origin
975+
976+ (void )state ;
977+ char * path = generate_include ("foo.baz. TXT foobar" );
978+ assert_non_null (path );
979+ char dummy [64 ];
980+ #define FMT \
981+ "foo.bar. TXT foobar\n" \
982+ "$INCLUDE \"%s\" baz.\n" \
983+ "foo TXT foobar"
984+ int length = snprintf (dummy , sizeof (dummy ), FMT , path );
985+ assert_true (length > 0 && length < INT_MAX - ZONE_PADDING_SIZE );
986+ char * include = malloc ((size_t )length + 1 + ZONE_PADDING_SIZE );
987+ assert_non_null (include );
988+ (void )snprintf (include , (size_t )length + 1 , FMT , path );
989+ #undef FMT
990+
991+ size_t count = 0 ;
992+ zone_parser_t parser ;
993+ zone_name_buffer_t name ;
994+ zone_rdata_buffer_t rdata ;
995+ zone_buffers_t buffers = { 1 , & name , & rdata };
996+ zone_options_t options = { 0 };
997+ static const uint8_t origin [] = { 3 , 'b' , 'a' , 'r' , 0 };
998+
999+ options .accept .callback = & reinstate_callback ;
1000+ options .origin .octets = origin ;
1001+ options .origin .length = sizeof (origin );
1002+ options .default_ttl = 3600 ;
1003+ options .default_class = 1 ;
1004+
1005+ int32_t code = zone_parse_string (& parser , & options , & buffers , include , strlen (include ), & count );
1006+ remove_include (path );
1007+ free (path );
1008+ free (include );
1009+ assert_int_equal (code , ZONE_SUCCESS );
1010+ assert_true (count == 3 );
1011+ }
0 commit comments