(pattern: &str, host: &str)
| 180 | } |
| 181 | |
| 182 | fn host_pattern_covers(pattern: &str, host: &str) -> bool { |
| 183 | let pattern_labels: Vec<&str> = pattern.split('.').collect(); |
| 184 | let host_labels: Vec<&str> = host.split('.').collect(); |
| 185 | let Some(first_pattern_label) = pattern_labels.first().copied() else { |
| 186 | return false; |
| 187 | }; |
| 188 | |
| 189 | if first_pattern_label == "**" { |
| 190 | let suffix = &pattern_labels[1..]; |
| 191 | let host_suffix = host_labels |
| 192 | .len() |
| 193 | .checked_sub(suffix.len()) |
| 194 | .map(|start| &host_labels[start..]); |
| 195 | return !suffix.is_empty() |
| 196 | && host_labels.len() > suffix.len() |
| 197 | && matches!(host_suffix, Some(host_suffix) if host_suffix == suffix); |
| 198 | } |
| 199 | |
| 200 | if !first_pattern_label.contains('*') { |
| 201 | return false; |
| 202 | } |
| 203 | |
| 204 | // Runtime host wildcards only apply in the first DNS label. Wildcards in |
| 205 | // later labels are not treated as policy globs here. |
| 206 | pattern_labels.len() == host_labels.len() |
| 207 | && pattern_labels[1..] == host_labels[1..] |
| 208 | && wildcard_label_matches(first_pattern_label, host_labels[0]) |
| 209 | } |
| 210 | |
| 211 | fn wildcard_label_matches(pattern: &str, label: &str) -> bool { |
| 212 | if pattern == "*" { |
no test coverage detected