fix(tvix/eval): correctly escape ${ in strings
				
					
				
			Without this escape, it is possible for Nix to produce escaped representations which are not literal Nix values again. This was fixed in upstream Nix in https://github.com/NixOS/nix/pull/4012 (though only for eval, not in the REPL) and the updated test is picked from upstream after that commit. Because we run the C++ Nix tests against our test suite as well, this also bumps our custom Nix 2.3 to a commit that includes the cherry-picked fix from the PR above. Change-Id: I478547ade65f655c606ec46f7143932064192283 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6271 Reviewed-by: grfn <grfn@gws.fyi> Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
This commit is contained in:
		
							parent
							
								
									265393301e
								
							
						
					
					
						commit
						39b01c3029
					
				
					 4 changed files with 19 additions and 14 deletions
				
			
		|  | @ -90,13 +90,14 @@ impl NixString { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| fn nix_escape_char(ch: char) -> Option<&'static str> { | ||||
|     match ch { | ||||
|         '\\' => Some("\\\\"), | ||||
|         '"' => Some("\\\""), | ||||
|         '\n' => Some("\\n"), | ||||
|         '\t' => Some("\\t"), | ||||
|         '\r' => Some("\\r"), | ||||
| fn nix_escape_char(ch: char, next: Option<&char>) -> Option<&'static str> { | ||||
|     match (ch, next) { | ||||
|         ('\\', _) => Some("\\\\"), | ||||
|         ('"', _) => Some("\\\""), | ||||
|         ('\n', _) => Some("\\n"), | ||||
|         ('\t', _) => Some("\\t"), | ||||
|         ('\r', _) => Some("\\r"), | ||||
|         ('$', Some('{')) => Some("\\$"), | ||||
|         _ => None, | ||||
|     } | ||||
| } | ||||
|  | @ -106,14 +107,17 @@ fn nix_escape_char(ch: char) -> Option<&'static str> { | |||
| //
 | ||||
| // Note that this does not add the outer pair of surrounding quotes.
 | ||||
| fn nix_escape_string(input: &str) -> Cow<str> { | ||||
|     for (i, c) in input.chars().enumerate() { | ||||
|         if let Some(esc) = nix_escape_char(c) { | ||||
|     let mut iter = input.chars().enumerate().peekable(); | ||||
| 
 | ||||
|     while let Some((i, c)) = iter.next() { | ||||
|         if let Some(esc) = nix_escape_char(c, iter.peek().map(|(_, c)| c)) { | ||||
|             let mut escaped = String::with_capacity(input.len()); | ||||
|             escaped.push_str(&input[..i]); | ||||
|             escaped.push_str(esc); | ||||
| 
 | ||||
|             for c in input[i + 1..].chars() { | ||||
|                 match nix_escape_char(c) { | ||||
|             let mut inner_iter = input[i + 1..].chars().peekable(); | ||||
|             while let Some(c) = inner_iter.next() { | ||||
|                 match nix_escape_char(c, inner_iter.peek()) { | ||||
|                     Some(esc) => escaped.push_str(esc), | ||||
|                     None => escaped.push(c), | ||||
|                 } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue