From 96f8691c8d656ae92d1cb2ed5b5fdb2dda677cf6 Mon Sep 17 00:00:00 2001 From: JT <547158+jntrnr@users.noreply.github.com> Date: Mon, 2 May 2022 09:49:31 +1200 Subject: [PATCH] More escaping/unescaping fixes (#5403) --- crates/nu-cli/src/commands.rs | 16 ++---------- crates/nu-test-support/src/macros.rs | 17 ++++++++++++- src/main.rs | 38 ++++++++++++++-------------- 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/crates/nu-cli/src/commands.rs b/crates/nu-cli/src/commands.rs index cffbcb0d0..a3a42f165 100644 --- a/crates/nu-cli/src/commands.rs +++ b/crates/nu-cli/src/commands.rs @@ -2,7 +2,7 @@ use crate::util::report_error; use log::info; use miette::Result; use nu_engine::{convert_env_values, eval_block}; -use nu_parser::{parse, trim_quotes}; +use nu_parser::parse; use nu_protocol::engine::Stack; use nu_protocol::{ engine::{EngineState, StateDelta, StateWorkingSet}, @@ -22,19 +22,7 @@ pub fn evaluate_commands( let (block, delta) = { let mut working_set = StateWorkingSet::new(engine_state); - let (input, _) = if commands.item.starts_with('\'') - || commands.item.starts_with('"') - || commands.item.starts_with('`') - { - ( - trim_quotes(commands.item.as_bytes()), - commands.span.start + 1, - ) - } else { - (commands.item.as_bytes(), commands.span.start) - }; - - let (output, err) = parse(&mut working_set, None, input, false, &[]); + let (output, err) = parse(&mut working_set, None, commands.item.as_bytes(), false, &[]); if let Some(err) = err { report_error(&working_set, &err); diff --git a/crates/nu-test-support/src/macros.rs b/crates/nu-test-support/src/macros.rs index 794b3c899..322ec2d85 100644 --- a/crates/nu-test-support/src/macros.rs +++ b/crates/nu-test-support/src/macros.rs @@ -21,6 +21,21 @@ macro_rules! nu { pub use std::process::{Command, Stdio}; pub use $crate::NATIVE_PATH_ENV_VAR; + pub fn escape_quote_string(input: String) -> String { + let mut output = String::with_capacity(input.len() + 2); + output.push('"'); + + for c in input.chars() { + if c == '"' || c == '\\' { + output.push('\\'); + } + output.push(c); + } + + output.push('"'); + output + } + // let commands = &*format!( // " // {} @@ -58,7 +73,7 @@ macro_rules! nu { // .arg("--no-history") // .arg("--config-file") // .arg($crate::fs::DisplayPath::display_path(&$crate::fs::fixtures().join("playground/config/default.toml"))) - .arg(format!("-c '{}'", $crate::fs::DisplayPath::display_path(&path))) + .arg(format!("-c {}", escape_quote_string($crate::fs::DisplayPath::display_path(&path)))) .stdout(Stdio::piped()) // .stdin(Stdio::piped()) .stderr(Stdio::piped()) diff --git a/src/main.rs b/src/main.rs index 5d0377b6e..f7276b4a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -86,11 +86,7 @@ fn main() -> Result<()> { } else if arg.starts_with('-') { // Cool, it's a flag let flag_value = match arg.as_ref() { - "--commands" | "-c" => { - // FIXME: Use proper quoting. `escape_quote_string()` can't be used for now due to https://github.com/nushell/nushell/issues/5383. - - args.next().map(|a| format!("`{}`", a)) - } + "--commands" | "-c" => args.next().map(|a| escape_quote_string(&a)), "--config" | "--env-config" => args.next().map(|a| escape_quote_string(&a)), "--log-level" | "--testbin" | "--threads" | "-t" => args.next(), _ => None, @@ -329,23 +325,27 @@ fn parse_commandline_args( fn extract_contents( expression: Option, - engine_state: &mut EngineState, - ) -> Option> { - expression.map(|expr| { - let contents = engine_state.get_span_contents(&expr.span); - - Spanned { - item: String::from_utf8_lossy(contents).to_string(), - span: expr.span, + ) -> Result>, ShellError> { + if let Some(expr) = expression { + let str = expr.as_string(); + if let Some(str) = str { + Ok(Some(Spanned { + item: str, + span: expr.span, + })) + } else { + Err(ShellError::TypeMismatch("string".into(), expr.span)) } - }) + } else { + Ok(None) + } } - let commands = extract_contents(commands, engine_state); - let testbin = extract_contents(testbin, engine_state); - let config_file = extract_contents(config_file, engine_state); - let env_file = extract_contents(env_file, engine_state); - let log_level = extract_contents(log_level, engine_state); + let commands = extract_contents(commands)?; + let testbin = extract_contents(testbin)?; + let config_file = extract_contents(config_file)?; + let env_file = extract_contents(env_file)?; + let log_level = extract_contents(log_level)?; let help = call.has_flag("help");