Remove external name exceptions (#5115)

This commit is contained in:
JT 2022-04-07 14:01:31 +12:00 committed by GitHub
parent 591fb4bd36
commit ef1934a7ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 45 additions and 147 deletions

View file

@ -56,10 +56,6 @@ pub fn evaluate_commands(
}
};
// Make a note of the exceptions we see for externals that look like math expressions
let exceptions = crate::util::external_exceptions(engine_state, stack);
engine_state.external_exceptions = exceptions;
// Merge the delta in case env vars changed in the config
match nu_engine::env::current_dir(engine_state, stack) {
Ok(cwd) => {

View file

@ -27,10 +27,6 @@ pub fn evaluate_file(
std::process::exit(1);
}
// Make a note of the exceptions we see for externals that look like math expressions
let exceptions = crate::util::external_exceptions(engine_state, stack);
engine_state.external_exceptions = exceptions;
let file = std::fs::read(&path).into_diagnostic()?;
let mut working_set = StateWorkingSet::new(engine_state);

View file

@ -83,10 +83,6 @@ pub fn evaluate_repl(
report_error(&working_set, &e);
}
// Make a note of the exceptions we see for externals that look like math expressions
let exceptions = crate::util::external_exceptions(engine_state, stack);
engine_state.external_exceptions = exceptions;
// seed env vars
stack.add_env_var(
"CMD_DURATION_MS".into(),
@ -356,10 +352,6 @@ pub fn evaluate_repl(
let _ = std::env::set_current_dir(path);
engine_state.env_vars.insert("PWD".into(), cwd);
}
// Make a note of the exceptions we see for externals that look like math expressions
let exceptions = crate::util::external_exceptions(engine_state, stack);
engine_state.external_exceptions = exceptions;
}
Ok(Signal::CtrlC) => {
// `Reedline` clears the line content. New prompt is shown

View file

@ -326,98 +326,6 @@ fn set_last_exit_code(stack: &mut Stack, exit_code: i64) {
);
}
fn seems_like_number(bytes: &[u8]) -> bool {
if bytes.is_empty() {
false
} else {
let b = bytes[0];
b == b'0'
|| b == b'1'
|| b == b'2'
|| b == b'3'
|| b == b'4'
|| b == b'5'
|| b == b'6'
|| b == b'7'
|| b == b'8'
|| b == b'9'
|| b == b'('
|| b == b'{'
|| b == b'['
|| b == b'$'
|| b == b'"'
|| b == b'\''
|| b == b'-'
}
}
/// Finds externals that have names that look like math expressions
pub fn external_exceptions(engine_state: &EngineState, stack: &Stack) -> Vec<Vec<u8>> {
let mut executables = vec![];
if let Some(path) = stack.get_env_var(engine_state, "PATH") {
match path {
Value::List { vals, .. } => {
for val in vals {
let path = val.as_string();
if let Ok(path) = path {
if let Ok(mut contents) = std::fs::read_dir(path) {
while let Some(Ok(item)) = contents.next() {
if is_executable::is_executable(&item.path()) {
if let Ok(name) = item.file_name().into_string() {
if seems_like_number(name.as_bytes()) {
let name = name.as_bytes().to_vec();
executables.push(name);
}
}
if let Some(name) = item.path().file_stem() {
let name = name.to_string_lossy();
if seems_like_number(name.as_bytes()) {
let name = name.as_bytes().to_vec();
executables.push(name);
}
}
}
}
}
}
}
}
Value::String { val, .. } => {
for path in std::env::split_paths(&val) {
let path = path.to_string_lossy().to_string();
if let Ok(mut contents) = std::fs::read_dir(path) {
while let Some(Ok(item)) = contents.next() {
if is_executable::is_executable(&item.path()) {
if let Ok(name) = item.file_name().into_string() {
if seems_like_number(name.as_bytes()) {
let name = name.as_bytes().to_vec();
executables.push(name);
}
}
if let Some(name) = item.path().file_stem() {
let name = name.to_string_lossy();
if seems_like_number(name.as_bytes()) {
let name = name.as_bytes().to_vec();
executables.push(name);
}
}
}
}
}
}
}
_ => {}
}
}
executables
}
pub fn report_error(
working_set: &StateWorkingSet,
error: &(dyn miette::Diagnostic + Send + Sync + 'static),

View file

@ -44,7 +44,12 @@ fn is_identifier_byte(b: u8) -> bool {
b != b'.' && b != b'[' && b != b'(' && b != b'{'
}
pub fn is_math_expression_like(bytes: &[u8]) -> bool {
pub fn is_math_expression_like(
working_set: &mut StateWorkingSet,
span: Span,
expand_aliases_denylist: &[usize],
) -> bool {
let bytes = working_set.get_span_contents(span);
if bytes.is_empty() {
return false;
}
@ -55,17 +60,7 @@ pub fn is_math_expression_like(bytes: &[u8]) -> bool {
let b = bytes[0];
b == b'0'
|| b == b'1'
|| b == b'2'
|| b == b'3'
|| b == b'4'
|| b == b'5'
|| b == b'6'
|| b == b'7'
|| b == b'8'
|| b == b'9'
|| b == b'('
if b == b'('
|| b == b'{'
|| b == b'['
|| b == b'$'
@ -73,6 +68,34 @@ pub fn is_math_expression_like(bytes: &[u8]) -> bool {
|| b == b'\''
|| b == b'`'
|| b == b'-'
{
return true;
}
if parse_number(bytes, span).1.is_none() {
return true;
}
if parse_filesize(working_set, span).1.is_none() {
return true;
}
if parse_duration(working_set, span).1.is_none() {
return true;
}
if parse_binary(working_set, span).1.is_none() {
return true;
}
if parse_range(working_set, span, expand_aliases_denylist)
.1
.is_none()
{
return true;
}
false
}
fn is_identifier(bytes: &[u8]) -> bool {
@ -869,20 +892,12 @@ pub fn parse_call(
for word_span in spans[cmd_start..].iter() {
// Find the longest group of words that could form a command
let bytes = working_set.get_span_contents(*word_span);
if is_math_expression_like(bytes)
&& bytes != b"true"
&& bytes != b"false"
&& bytes != b"null"
&& bytes != b"not"
&& !working_set
.permanent_state
.external_exceptions
.iter()
.any(|x| x == bytes)
{
break;
if is_math_expression_like(working_set, *word_span, expand_aliases_denylist) {
let bytes = working_set.get_span_contents(*word_span);
if bytes != b"true" && bytes != b"false" && bytes != b"null" && bytes != b"not" {
break;
}
}
name_spans.push(*word_span);
@ -1951,7 +1966,7 @@ pub fn parse_datetime(
/// Parse a duration type, eg '10day'
pub fn parse_duration(
working_set: &mut StateWorkingSet,
working_set: &StateWorkingSet,
span: Span,
) -> (Expression, Option<ParseError>) {
trace!("parsing: duration");
@ -2055,7 +2070,7 @@ pub fn parse_duration_bytes(bytes: &[u8], span: Span) -> Option<Expression> {
/// Parse a unit type, eg '10kb'
pub fn parse_filesize(
working_set: &mut StateWorkingSet,
working_set: &StateWorkingSet,
span: Span,
) -> (Expression, Option<ParseError>) {
trace!("parsing: duration");
@ -4228,17 +4243,12 @@ pub fn parse_expression(
);
}
let bytes = working_set.get_span_contents(spans[pos]);
let (output, err) = if is_math_expression_like(bytes)
&& !working_set
.permanent_state
.external_exceptions
.iter()
.any(|x| x == bytes)
let (output, err) = if is_math_expression_like(working_set, spans[pos], expand_aliases_denylist)
{
parse_math_expression(working_set, &spans[pos..], None, expand_aliases_denylist)
} else {
let bytes = working_set.get_span_contents(spans[pos]);
// For now, check for special parses of certain keywords
match bytes {
b"def" => (

View file

@ -178,9 +178,6 @@ pub struct EngineState {
pub env_vars: im::HashMap<String, Value>,
#[cfg(feature = "plugin")]
pub plugin_signatures: Option<PathBuf>,
// A list of external commands that look like math expressions
pub external_exceptions: Vec<Vec<u8>>,
}
pub const NU_VARIABLE_ID: usize = 0;
@ -210,7 +207,6 @@ impl EngineState {
env_vars: im::HashMap::new(),
#[cfg(feature = "plugin")]
plugin_signatures: None,
external_exceptions: vec![],
}
}