@@ -797,9 +797,9 @@ fn verify_app_compose_policy(app_compose: &AppCompose) -> Result<()> {
797797
798798fn verify_manifest_feature_requirements ( app_compose : & AppCompose ) -> Result < ( ) > {
799799 let manifest_version = verify_manifest_version ( app_compose) ?;
800- if app_compose. requirements . is_some ( ) && manifest_version != MANIFEST_VERSION_3 {
800+ if app_compose. requirements . is_some ( ) && manifest_version < MANIFEST_VERSION_3 {
801801 bail ! (
802- "requirements requires manifest_version = = {MANIFEST_VERSION_3}; use string manifest_version \" {MANIFEST_VERSION_3}\" so older guests fail closed"
802+ "requirements requires manifest_version > = {MANIFEST_VERSION_3}; use string manifest_version \" {MANIFEST_VERSION_3}\" so older guests fail closed"
803803 ) ;
804804 }
805805 Ok ( ( ) )
@@ -900,16 +900,21 @@ fn os_release_value(content: &str, key: &str) -> Option<String> {
900900
901901fn unquote_os_release_value ( value : & str ) -> String {
902902 let value = value. trim ( ) ;
903- let bytes = value. as_bytes ( ) ;
904- if bytes. len ( ) >= 2
905- && ( ( bytes[ 0 ] == b'"' && bytes[ bytes. len ( ) - 1 ] == b'"' )
906- || ( bytes[ 0 ] == b'\'' && bytes[ bytes. len ( ) - 1 ] == b'\'' ) )
907- {
908- let inner = & value[ 1 ..value. len ( ) - 1 ] ;
909- return inner
910- . replace ( "\\ \" " , "\" " )
911- . replace ( "\\ '" , "'" )
912- . replace ( "\\ \\ " , "\\ " ) ;
903+ if let Some ( inner) = value. strip_prefix ( '"' ) . and_then ( |v| v. strip_suffix ( '"' ) ) {
904+ // Double-quoted: a backslash escapes the next character.
905+ let mut unescaped = String :: with_capacity ( inner. len ( ) ) ;
906+ let mut chars = inner. chars ( ) ;
907+ while let Some ( c) = chars. next ( ) {
908+ match c {
909+ '\\' => unescaped. push ( chars. next ( ) . unwrap_or ( '\\' ) ) ,
910+ _ => unescaped. push ( c) ,
911+ }
912+ }
913+ return unescaped;
914+ }
915+ if let Some ( inner) = value. strip_prefix ( '\'' ) . and_then ( |v| v. strip_suffix ( '\'' ) ) {
916+ // Single-quoted: shell single quotes have no escape sequences.
917+ return inner. to_string ( ) ;
913918 }
914919 value. to_string ( )
915920}
@@ -2204,3 +2209,19 @@ VERSION_ID="0.6.1"
22042209 Some ( "0.6.1" )
22052210 ) ;
22062211}
2212+
2213+ #[ test]
2214+ fn test_unquote_os_release_value_handles_quoting_styles ( ) {
2215+ assert_eq ! ( unquote_os_release_value( "0.6.1" ) , "0.6.1" ) ;
2216+ assert_eq ! ( unquote_os_release_value( "\" 0.6.1\" " ) , "0.6.1" ) ;
2217+ assert_eq ! ( unquote_os_release_value( "'0.6.1'" ) , "0.6.1" ) ;
2218+ // Double-quoted: backslash escapes the next character.
2219+ assert_eq ! ( unquote_os_release_value( r#""a\"b""# ) , "a\" b" ) ;
2220+ assert_eq ! ( unquote_os_release_value( r#""a\\b""# ) , r"a\b" ) ;
2221+ assert_eq ! ( unquote_os_release_value( r#""a\\\"b""# ) , r#"a\"b"# ) ;
2222+ // Single-quoted: no escape sequences.
2223+ assert_eq ! ( unquote_os_release_value( r"'a\\b'" ) , r"a\\b" ) ;
2224+ // Unbalanced/degenerate quotes are returned verbatim.
2225+ assert_eq ! ( unquote_os_release_value( "\" " ) , "\" " ) ;
2226+ assert_eq ! ( unquote_os_release_value( "\" a" ) , "\" a" ) ;
2227+ }
0 commit comments