File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1662,36 +1662,36 @@ pub unsafe extern "C" fn __res_state() -> *mut c_void {
16621662
16631663fn hostname_labels_ok ( bytes : & [ u8 ] ) -> bool {
16641664 if bytes. is_empty ( ) {
1665- return false ;
1665+ return true ;
16661666 }
16671667
16681668 let mut label_len: usize = 0 ;
1669- let mut last = b'.' ;
1669+ let mut at_label_start = true ;
16701670 for & c in bytes {
16711671 if c == b'.' {
1672- if label_len == 0 || last == b'-' {
1672+ if label_len == 0 {
16731673 return false ;
16741674 }
16751675 label_len = 0 ;
1676- last = c ;
1677- } else if c. is_ascii_alphanumeric ( ) || c == b'-' {
1678- if label_len == 0 && c == b'-' {
1676+ at_label_start = true ;
1677+ } else if c. is_ascii_alphanumeric ( ) || c == b'-' || c == b'_' {
1678+ if at_label_start && c == b'-' {
16791679 return false ;
16801680 }
16811681 label_len += 1 ;
16821682 if label_len > 63 {
16831683 return false ;
16841684 }
1685- last = c ;
1685+ at_label_start = false ;
16861686 } else {
16871687 return false ;
16881688 }
16891689 }
16901690
1691- label_len != 0 && last != b'-'
1691+ label_len != 0 || bytes . last ( ) == Some ( & b'.' )
16921692}
16931693
1694- // res_hnok: hostname — letters, digits, hyphens only (RFC 952)
1694+ // res_hnok: glibc-compatible hostname-label predicate.
16951695#[ cfg_attr( not( debug_assertions) , unsafe ( no_mangle) ) ]
16961696pub unsafe extern "C" fn res_hnok ( dn : * const c_char ) -> c_int {
16971697 let Some ( bytes) = ( unsafe { dns_c_string_bytes ( dn) } ) else {
Original file line number Diff line number Diff line change 1+ #![ cfg( target_os = "linux" ) ]
2+ #![ allow( unsafe_code) ]
3+ //! Live host-glibc differential coverage for DNS label predicates.
4+ //!
5+ //! These predicates are consumed before resolver queries are assembled, so
6+ //! boundary labels must follow the host contract exactly rather than merely
7+ //! accepting the common alphanumeric cases.
8+
9+ use frankenlibc_abi:: glibc_internal_abi as fl;
10+ use std:: ffi:: CString ;
11+ use std:: os:: raw:: { c_char, c_int} ;
12+
13+ unsafe extern "C" {
14+ fn res_dnok ( name : * const c_char ) -> c_int ;
15+ fn res_hnok ( name : * const c_char ) -> c_int ;
16+ }
17+
18+ #[ test]
19+ fn resolver_label_boundaries_match_glibc ( ) {
20+ for raw in [
21+ "" ,
22+ "-bad.example" ,
23+ "bad-.example" ,
24+ "example.com." ,
25+ "two..dots" ,
26+ "_service._tcp.example" ,
27+ ] {
28+ let name = CString :: new ( raw) . unwrap ( ) ;
29+ let fl_hnok = unsafe { fl:: res_hnok ( name. as_ptr ( ) ) } ;
30+ let host_hnok = unsafe { res_hnok ( name. as_ptr ( ) ) } ;
31+ let fl_dnok = unsafe { fl:: res_dnok ( name. as_ptr ( ) ) } ;
32+ let host_dnok = unsafe { res_dnok ( name. as_ptr ( ) ) } ;
33+ assert_eq ! ( fl_hnok, host_hnok, "res_hnok({raw:?})" ) ;
34+ assert_eq ! ( fl_dnok, host_dnok, "res_dnok({raw:?})" ) ;
35+ }
36+ }
You can’t perform that action at this time.
0 commit comments