@@ -1404,44 +1404,74 @@ fn get_the_effective_directive_for_inline_checks(type_: InlineCheckType) -> &'st
14041404/// <https://www.w3.org/TR/CSP/#script-pre-request>
14051405fn script_directives_prerequest_check ( request : & Request , directive : & Directive ) -> CheckResult {
14061406 use CheckResult :: * ;
1407+ // Step 1. If request’s destination is script-like:
14071408 if request_is_script_like ( request) {
14081409 let source_list = SourceList ( & directive. value [ ..] ) ;
1410+ // Step 1.1. If the result of executing § 6.7.2.3 Does nonce match source list? on
1411+ // request’s cryptographic nonce metadata and this directive’s value is "Matches", return "Allowed".
14091412 if source_list. does_nonce_match_source_list ( & request. nonce ) == Matches {
14101413 return Allowed ;
14111414 }
1415+ // Step 1.2. If the result of executing § 6.7.2.4 Does integrity metadata match source list? on
1416+ // request’s integrity metadata and this directive’s value is "Matches", return "Allowed".
14121417 if source_list. does_integrity_metadata_match_source_list ( & request. integrity_metadata ) == Matches {
14131418 return Allowed ;
14141419 }
1420+ // Step 1.3. If directive’s value contains a source expression that is an
1421+ // ASCII case-insensitive match for the "'strict-dynamic'" keyword-source:
14151422 if directive. value . iter ( ) . any ( |ex| ascii_case_insensitive_match ( ex, "'strict-dynamic'" ) ) {
1423+ // Step 1.3.1. If the request’s parser metadata is "parser-inserted", return "Blocked".
14161424 if request. parser_metadata == ParserMetadata :: ParserInserted {
14171425 return Blocked ;
1418- } else {
1419- return Allowed ;
14201426 }
1427+ // Otherwise, return "Allowed".
1428+ return Allowed ;
14211429 }
14221430
1431+ // Step 1.4. If the result of executing § 6.7.2.5 Does request match source list? on
1432+ // request, directive’s value, and policy, is "Does Not Match", return "Blocked".
14231433 if source_list. does_request_match_source_list ( request) == DoesNotMatch {
14241434 return Blocked ;
14251435 }
14261436 }
1437+ // Step 2. Return "Allowed".
14271438 Allowed
14281439}
14291440
14301441/// https://www.w3.org/TR/CSP/#script-post-request
14311442fn script_directives_postrequest_check ( request : & Request , response : & Response , directive : & Directive ) -> CheckResult {
14321443 use CheckResult :: * ;
1444+ // Step 1. If request’s destination is script-like:
14331445 if request_is_script_like ( request) {
1446+ // Step 1.1. Call potentially report hash with response, request, directive and policy.
1447+ // TODO
14341448 let source_list = SourceList ( & directive. value [ ..] ) ;
1449+ // Step 1.2. If the result of executing § 6.7.2.3 Does nonce match source list? on
1450+ // request’s cryptographic nonce metadata and this directive’s value is "Matches", return "Allowed".
14351451 if source_list. does_nonce_match_source_list ( & request. nonce ) == Matches {
14361452 return Allowed ;
14371453 }
1438- if directive. value . iter ( ) . any ( |ex| ascii_case_insensitive_match ( ex, "'strict-dynamic'" ) ) && request. parser_metadata != ParserMetadata :: ParserInserted {
1454+ // Step 1.3. If the result of executing § 6.7.2.4 Does integrity metadata match source list? on
1455+ // request’s integrity metadata and this directive’s value is "Matches", return "Allowed".
1456+ if source_list. does_integrity_metadata_match_source_list ( & request. integrity_metadata ) == Matches {
1457+ return Allowed ;
1458+ }
1459+ // Step 1.4. If directive’s value contains "'strict-dynamic'":
1460+ if directive. value . iter ( ) . any ( |ex| ascii_case_insensitive_match ( ex, "'strict-dynamic'" ) ) {
1461+ // Step 1.4.1. If the request’s parser metadata is "parser-inserted", return "Blocked".
1462+ if request. parser_metadata == ParserMetadata :: ParserInserted {
1463+ return Blocked ;
1464+ }
1465+ // Otherwise, return "Allowed".
14391466 return Allowed ;
14401467 }
1468+ // Step 1.5. If the result of executing § 6.7.2.6 Does response to request match source list? on
1469+ // response, request, directive’s value, and policy, is "Does Not Match", return "Blocked".
14411470 if source_list. does_response_to_request_match_source_list ( request, response) == DoesNotMatch {
14421471 return Blocked ;
14431472 }
14441473 }
1474+ // Step 2. Return "Allowed".
14451475 Allowed
14461476}
14471477
@@ -1820,39 +1850,50 @@ fn does_url_match_expression_in_origin_with_redirect_count(
18201850}
18211851
18221852/// https://www.w3.org/TR/CSP/#match-hosts
1823- fn host_part_match ( a : & str , b : & str ) -> MatchResult {
1824- debug_assert ! ( !a. is_empty( ) ) ;
1825- if a. is_empty ( ) {
1853+ fn host_part_match ( pattern : & str , host : & str ) -> MatchResult {
1854+ debug_assert ! ( !host. is_empty( ) ) ;
1855+ // Step 1. If host is not a domain, return "Does Not Match".
1856+ if host. is_empty ( ) {
18261857 return DoesNotMatch ;
18271858 }
1828- if a. as_bytes ( ) [ 0 ] == b'*' {
1829- let remaining = & a[ 1 ..] ;
1830- debug_assert_eq ! ( & remaining[ ..1 ] , "." ) ;
1831- if remaining. len ( ) > b. len ( ) {
1832- return DoesNotMatch ;
1833- }
1834- let remaining_b = & b[ ( b. len ( ) -remaining. len ( ) ) ..] ;
1835- debug_assert_eq ! ( remaining_b. len( ) , remaining. len( ) ) ;
1836- if ascii_case_insensitive_match ( remaining, remaining_b) {
1859+ if pattern. as_bytes ( ) [ 0 ] == b'*' {
1860+ // Step 2. If pattern is "*", return "Matches".
1861+ if pattern. len ( ) == 1 {
18371862 return Matches ;
1838- } else {
1863+ }
1864+ // Step 3. If pattern starts with "*.":
1865+ if pattern. as_bytes ( ) [ 1 ] == b'.' {
1866+ // Step 3.1 Let remaining be pattern with the leading U+002A (*) removed and ASCII lowercased.
1867+ let remaining_pattern = & pattern[ 1 ..] ;
1868+ if remaining_pattern. len ( ) > host. len ( ) {
1869+ return DoesNotMatch ;
1870+ }
1871+ let remaining_host = & host[ ( host. len ( ) -remaining_pattern. len ( ) ) ..] ;
1872+ debug_assert_eq ! ( remaining_host. len( ) , remaining_pattern. len( ) ) ;
1873+ // Step 3.2. If host to ASCII lowercase ends with remaining, then return "Matches".
1874+ if ascii_case_insensitive_match ( remaining_pattern, remaining_host) {
1875+ return Matches ;
1876+ }
1877+ // Step 3.3 Return "Does Not Match".
18391878 return DoesNotMatch ;
18401879 }
18411880 }
1842- if !ascii_case_insensitive_match ( a, b) {
1881+ // Step 4. If pattern is not an ASCII case-insensitive match for host, return "Does Not Match".
1882+ if !ascii_case_insensitive_match ( pattern, host) {
18431883 return DoesNotMatch ;
18441884 }
18451885 static IPV4_ADDRESS_RULE : Lazy < Regex > =
18461886 Lazy :: new ( || Regex :: new ( r#"([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"# ) . unwrap ( ) ) ;
1847- if IPV4_ADDRESS_RULE . is_match ( a ) && a != "127.0.0.1" {
1887+ if IPV4_ADDRESS_RULE . is_match ( pattern ) && pattern != "127.0.0.1" {
18481888 return DoesNotMatch ;
18491889 }
18501890 // The spec uses the phrase "if A is an IPv6 address", without giving specific instructions on
18511891 // how to tell if this is the case. In URLs, IPv6 addresses start with `[`, so let's go with that.
18521892 // See https://url.spec.whatwg.org/#host-parsing
1853- if a . as_bytes ( ) [ 0 ] == b'[' {
1893+ if pattern . as_bytes ( ) [ 0 ] == b'[' {
18541894 return DoesNotMatch ;
18551895 }
1896+ // Step 5. Return "Matches".
18561897 Matches
18571898}
18581899
0 commit comments