@@ -1727,6 +1727,46 @@ rr_rdf(obj,n)
17271727 OUTPUT :
17281728 RETVAL
17291729
1730+ bool
1731+ rr_check_rd_count (obj )
1732+ Zonemaster ::LDNS ::RR obj ;
1733+ CODE :
1734+ ldns_rr_type rr_type = ldns_rr_get_type (obj );
1735+ ldns_rr_descriptor * desc = ldns_rr_descript (rr_type );
1736+ size_t rd_min = ldns_rr_descriptor_minimum (desc );
1737+ size_t rd_max = ldns_rr_descriptor_maximum (desc );
1738+ size_t rd_count = ldns_rr_rd_count (obj );
1739+
1740+ // Workaround for when the last field is variable length with length
1741+ // zero, and ldns represents this by omitting the last field from
1742+ // the field list.
1743+ if (rd_min > 0 && rd_min == rd_max )
1744+ {
1745+ switch (ldns_rr_descriptor_field_type (desc ,rd_min - 1 ))
1746+ {
1747+ // This list is taken from ldns_wire2rdf()
1748+ case LDNS_RDF_TYPE_APL :
1749+ case LDNS_RDF_TYPE_B64 :
1750+ case LDNS_RDF_TYPE_HEX :
1751+ case LDNS_RDF_TYPE_NSEC :
1752+ case LDNS_RDF_TYPE_UNKNOWN :
1753+ case LDNS_RDF_TYPE_SERVICE :
1754+ case LDNS_RDF_TYPE_LOC :
1755+ case LDNS_RDF_TYPE_WKS :
1756+ case LDNS_RDF_TYPE_NSAP :
1757+ case LDNS_RDF_TYPE_ATMA :
1758+ case LDNS_RDF_TYPE_IPSECKEY :
1759+ case LDNS_RDF_TYPE_LONG_STR :
1760+ case LDNS_RDF_TYPE_AMTRELAY :
1761+ case LDNS_RDF_TYPE_NONE :
1762+ rd_min -= 1 ;
1763+ }
1764+ }
1765+
1766+ RETVAL = rd_min <= rd_count && rd_count <= rd_max ;
1767+ OUTPUT :
1768+ RETVAL
1769+
17301770void
17311771rr_DESTROY (obj )
17321772 Zonemaster ::LDNS ::RR obj ;
@@ -2275,20 +2315,36 @@ rr_nsec3_iterations(obj)
22752315SV *
22762316rr_nsec3_salt (obj )
22772317 Zonemaster ::LDNS ::RR ::NSEC3 obj ;
2278- PPCODE :
2279- if ( ldns_nsec3_salt_length ( obj ) > 0 )
2280- {
2281- ldns_rdf * buf = ldns_nsec3_salt ( obj );
2282- ST ( 0 ) = sv_2mortal ( newSVpvn ((char * )ldns_rdf_data ( buf ), ldns_rdf_size ( buf ) ));
2283- ldns_rdf_deep_free ( buf );
2318+ CODE :
2319+ {
2320+ uint8_t * salt = ldns_nsec3_salt_data ( obj );
2321+ if ( salt ) {
2322+ RETVAL = newSVpvn ((char * )salt , ldns_nsec3_salt_length ( obj ));
2323+ LDNS_FREE ( salt );
22842324 }
2325+ }
2326+ OUTPUT :
2327+ RETVAL
22852328
22862329SV *
22872330rr_nsec3_next_owner (obj )
22882331 Zonemaster ::LDNS ::RR ::NSEC3 obj ;
2332+ INIT :
2333+ ldns_rdf * buf = NULL ;
2334+ size_t size ;
22892335 CODE :
2290- ldns_rdf * buf = ldns_nsec3_next_owner (obj );
2291- RETVAL = newSVpvn ((char * )ldns_rdf_data (buf ), ldns_rdf_size (buf ));
2336+ buf = ldns_nsec3_next_owner (obj );
2337+ if (!buf ) {
2338+ XSRETURN_UNDEF ;
2339+ }
2340+ size = ldns_rdf_size (buf );
2341+ if (size < 1 ) {
2342+ XSRETURN_UNDEF ;
2343+ }
2344+
2345+ /* ldns_rdf_data(buf) points to the hashed next owner name preceded by a
2346+ * length byte, which we don't want. */
2347+ RETVAL = newSVpvn ((char * )(ldns_rdf_data (buf ) + 1 ), size - 1 );
22922348 OUTPUT :
22932349 RETVAL
22942350
@@ -2337,22 +2393,45 @@ bool
23372393rr_nsec3_covers (obj ,name )
23382394 Zonemaster ::LDNS ::RR ::NSEC3 obj ;
23392395 const char * name ;
2396+ INIT :
2397+ /* Sanity test on owner name */
2398+ if (ldns_dname_label_count (ldns_rr_owner (obj )) == 0 )
2399+ XSRETURN_UNDEF ;
2400+
2401+ /* Sanity test on hashed next owner field */
2402+ ldns_rdf * next_owner = ldns_nsec3_next_owner (obj );
2403+ if (!next_owner || ldns_rdf_size (next_owner ) <= 1 )
2404+ XSRETURN_UNDEF ;
2405+
23402406 CODE :
23412407 {
23422408 ldns_rr * clone ;
23432409 ldns_rdf * dname ;
23442410 ldns_rdf * hashed ;
23452411 ldns_rdf * chopped ;
23462412
2347- clone = ldns_rr_clone (obj );
23482413 dname = ldns_rdf_new_frm_str (LDNS_RDF_TYPE_DNAME , name );
2414+ if (!dname )
2415+ XSRETURN_UNDEF ;
2416+
23492417 ldns_dname2canonical (dname );
2418+
2419+ chopped = ldns_dname_left_chop (dname );
2420+ if (!chopped ) {
2421+ ldns_rdf_deep_free (dname );
2422+ XSRETURN_UNDEF ;
2423+ }
2424+
2425+ clone = ldns_rr_clone (obj );
23502426 ldns_rr2canonical (clone );
23512427 hashed = ldns_nsec3_hash_name_frm_nsec3 (clone , dname );
2352- chopped = ldns_dname_left_chop ( dname );
2428+
23532429 ldns_rdf_deep_free (dname );
2430+
23542431 ldns_dname_cat (hashed ,chopped );
2432+
23552433 RETVAL = ldns_nsec_covers_name (clone ,hashed );
2434+
23562435 ldns_rdf_deep_free (hashed );
23572436 ldns_rdf_deep_free (chopped );
23582437 ldns_rr_free (clone );
@@ -2390,12 +2469,17 @@ rr_nsec3param_iterations(obj)
23902469SV *
23912470rr_nsec3param_salt (obj )
23922471 Zonemaster ::LDNS ::RR ::NSEC3PARAM obj ;
2393- PPCODE :
2394- ldns_rdf * rdf = ldns_rr_rdf (obj ,3 );
2395- if (ldns_rdf_size (rdf ) > 0 )
2472+ CODE :
2473+ {
2474+ ldns_rdf * rdf = ldns_rr_rdf (obj , 3 );
2475+ size_t size = ldns_rdf_size (rdf );
2476+ if (size > 0 )
23962477 {
2397- mPUSHs ( newSVpvn ((char * )ldns_rdf_data (rdf ), ldns_rdf_size ( rdf )) );
2478+ RETVAL = newSVpvn ((char * )( ldns_rdf_data (rdf ) + 1 ), size - 1 );
23982479 }
2480+ }
2481+ OUTPUT :
2482+ RETVAL
23992483
24002484MODULE = Zonemaster ::LDNS PACKAGE = Zonemaster ::LDNS ::RR ::PTR PREFIX = rr_ptr_
24012485
0 commit comments