(
policy: &'a mut SandboxPolicy,
host: &str,
port: u32,
)
| 637 | } |
| 638 | |
| 639 | fn find_endpoint_mut<'a>( |
| 640 | policy: &'a mut SandboxPolicy, |
| 641 | host: &str, |
| 642 | port: u32, |
| 643 | ) -> Option<&'a mut NetworkEndpoint> { |
| 644 | // `_provider_*` rules are excluded from this lookup for the same reason |
| 645 | // they're excluded from `add_rule`'s endpoint-overlap fallback: callers |
| 646 | // (`AddAllowRules`, `AddDenyRules`) must not mutate provider-injected |
| 647 | // rules in place. If the operation should target a provider rule, the |
| 648 | // caller should reference it by its exact name through the merge ops |
| 649 | // that take a `rule_name`. Defense-in-depth: even if a future caller |
| 650 | // accidentally passes a composed policy here, `AddAllowRules` would no |
| 651 | // longer be able to expand a provider rule's `access` shorthand into |
| 652 | // wildcard `path: "**"` rules (which would mask the prover's narrowness |
| 653 | // verdict on agent contributions). |
| 654 | let mut keys: Vec<_> = policy.network_policies.keys().cloned().collect(); |
| 655 | keys.sort(); |
| 656 | let target_key = keys |
| 657 | .into_iter() |
| 658 | .filter(|k| !is_provider_rule_name(k)) |
| 659 | .find(|key| { |
| 660 | policy.network_policies.get(key).is_some_and(|rule| { |
| 661 | rule.endpoints |
| 662 | .iter() |
| 663 | .any(|endpoint| endpoint_matches_host_port(endpoint, host, port)) |
| 664 | }) |
| 665 | })?; |
| 666 | |
| 667 | policy |
| 668 | .network_policies |
| 669 | .get_mut(&target_key) |
| 670 | .and_then(|rule| { |
| 671 | rule.endpoints |
| 672 | .iter_mut() |
| 673 | .find(|endpoint| endpoint_matches_host_port(endpoint, host, port)) |
| 674 | }) |
| 675 | } |
| 676 | |
| 677 | fn endpoint_matches_host_port(endpoint: &NetworkEndpoint, host: &str, port: u32) -> bool { |
| 678 | endpoint.host.eq_ignore_ascii_case(host) && canonical_ports(endpoint).contains(&port) |
no test coverage detected