@@ -1293,16 +1293,22 @@ fn integrity_rank(scope: &str, labels: &[String], ctx: &PolicyContext) -> u8 {
12931293}
12941294
12951295fn integrity_rank_normalized ( normalized_scope : & str , labels : & [ String ] ) -> u8 {
1296- let is_multi_scope = normalized_scope. contains ( '|' ) ;
1296+ if normalized_scope. contains ( '|' ) {
1297+ // Multi-scope uses canonical "integrity=<base>;scopes=..." encoding.
1298+ for ( rank, ( prefix, base) ) in INTEGRITY_LEVELS . iter ( ) . enumerate ( ) . rev ( ) {
1299+ let expected = format_integrity_label ( prefix, normalized_scope, base) ;
1300+ if labels. iter ( ) . any ( |label| label == & expected) {
1301+ return ( rank + 1 ) as u8 ;
1302+ }
1303+ }
1304+ return 0 ;
1305+ }
12971306
12981307 // Check from highest to lowest.
12991308 for ( rank, ( prefix, base) ) in INTEGRITY_LEVELS . iter ( ) . enumerate ( ) . rev ( ) {
1300- let expected = is_multi_scope. then ( || format_integrity_label ( prefix, normalized_scope, base) ) ;
13011309 if labels
13021310 . iter ( )
1303- . any ( |label| {
1304- label_matches_normalized ( label, prefix, normalized_scope, base, expected. as_deref ( ) )
1305- } )
1311+ . any ( |label| label_matches_normalized ( label, prefix, normalized_scope, base) )
13061312 {
13071313 return ( rank + 1 ) as u8 ;
13081314 }
@@ -1316,13 +1322,9 @@ fn label_matches_normalized(
13161322 prefix : & str ,
13171323 scope : & str ,
13181324 base : & str ,
1319- expected_multi_scope : Option < & str > ,
13201325) -> bool {
13211326 if scope. is_empty ( ) {
13221327 label == base
1323- } else if let Some ( expected) = expected_multi_scope {
1324- // Multi-scope uses canonical "integrity=<base>;scopes=..." encoding.
1325- label == expected
13261328 } else {
13271329 label. strip_prefix ( prefix) == Some ( scope)
13281330 }
@@ -2395,37 +2397,38 @@ mod tests {
23952397 }
23962398
23972399 #[ test]
2398- fn test_label_matches_normalized_common_and_multiscope_paths ( ) {
2400+ fn test_label_matches_normalized_common_paths ( ) {
23992401 assert ! ( label_matches_normalized(
24002402 "approved:owner/repo" ,
24012403 label_constants:: WRITER_PREFIX ,
24022404 "owner/repo" ,
2403- label_constants:: WRITER_BASE ,
2404- None
2405- ) ) ;
2406- assert ! ( label_matches_normalized(
2407- "integrity=approved;scopes=owner/repo,owner/tool*" ,
2408- label_constants:: WRITER_PREFIX ,
2409- "owner/repo | owner/tool*" ,
2410- label_constants:: WRITER_BASE ,
2411- Some ( "integrity=approved;scopes=owner/repo,owner/tool*" )
2405+ label_constants:: WRITER_BASE
24122406 ) ) ;
24132407 assert ! ( label_matches_normalized(
24142408 label_constants:: READER_BASE ,
24152409 label_constants:: READER_PREFIX ,
24162410 "" ,
2417- label_constants:: READER_BASE ,
2418- None
2411+ label_constants:: READER_BASE
24192412 ) ) ;
24202413 assert ! ( !label_matches_normalized(
24212414 "approved:owner/repo" ,
24222415 label_constants:: MERGED_PREFIX ,
24232416 "owner/repo" ,
2424- label_constants:: MERGED_BASE ,
2425- None
2417+ label_constants:: MERGED_BASE
24262418 ) ) ;
24272419 }
24282420
2421+ #[ test]
2422+ fn test_integrity_rank_normalized_multiscope_path ( ) {
2423+ let scope = "owner/repo | owner/tool*" ;
2424+ let labels = vec ! [ format_integrity_label(
2425+ label_constants:: WRITER_PREFIX ,
2426+ scope,
2427+ label_constants:: WRITER_BASE ,
2428+ ) ] ;
2429+ assert_eq ! ( integrity_rank_normalized( scope, & labels) , 3 ) ;
2430+ }
2431+
24292432 #[ test]
24302433 fn test_integrity_for_level_mapping ( ) {
24312434 let ctx = test_ctx ( ) ;
0 commit comments