mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 04:45:04 +02:00
Protocol: debug_assert!() Span to reflect a valid slice (#6806)
Also enforce this by #[non_exhaustive] span such that going forward we cannot, in debug builds (1), construct invalid spans. The motivation for this stems from #6431 where I've seen crashes due to invalid slice indexing. My hope is this will mitigate such senarios 1. https://github.com/nushell/nushell/pull/6431#issuecomment-1278147241 # Description (description of your pull request here) # Tests Make sure you've done the following: - [ ] Add tests that cover your changes, either in the command examples, the crate/tests folder, or in the /tests folder. - [ ] Try to think about corner cases and various ways how your changes could break. Cover them with tests. - [ ] If adding tests is not possible, please document in the PR body a minimal example with steps on how to reproduce so one can verify your change works. Make sure you've run and fixed any issues with these commands: - [x] `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - [ ] `cargo clippy --workspace --features=extra -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` to check that you're using the standard code style - [ ] `cargo test --workspace --features=extra` to check that all the tests pass # Documentation - [ ] If your PR touches a user-facing nushell feature then make sure that there is an entry in the documentation (https://github.com/nushell/nushell.github.io) for the feature, and update it if necessary.
This commit is contained in:
committed by
GitHub
parent
e6cf18ea43
commit
850ecf648a
@ -94,10 +94,7 @@ impl CommandCompletion {
|
||||
value: String::from_utf8_lossy(&x.0).to_string(),
|
||||
description: x.1,
|
||||
extra: None,
|
||||
span: reedline::Span {
|
||||
start: span.start - offset,
|
||||
end: span.end - offset,
|
||||
},
|
||||
span: reedline::Span::new(span.start - offset, span.end - offset),
|
||||
append_whitespace: true,
|
||||
});
|
||||
|
||||
@ -108,10 +105,7 @@ impl CommandCompletion {
|
||||
value: String::from_utf8_lossy(&x).to_string(),
|
||||
description: None,
|
||||
extra: None,
|
||||
span: reedline::Span {
|
||||
start: span.start - offset,
|
||||
end: span.end - offset,
|
||||
},
|
||||
span: reedline::Span::new(span.start - offset, span.end - offset),
|
||||
append_whitespace: true,
|
||||
});
|
||||
|
||||
@ -128,10 +122,7 @@ impl CommandCompletion {
|
||||
value: x,
|
||||
description: None,
|
||||
extra: None,
|
||||
span: reedline::Span {
|
||||
start: span.start - offset,
|
||||
end: span.end - offset,
|
||||
},
|
||||
span: reedline::Span::new(span.start - offset, span.end - offset),
|
||||
append_whitespace: true,
|
||||
});
|
||||
|
||||
@ -187,10 +178,7 @@ impl Completer for CommandCompletion {
|
||||
let subcommands = if let Some(last) = last {
|
||||
self.complete_commands(
|
||||
working_set,
|
||||
Span {
|
||||
start: last.0.start,
|
||||
end: pos,
|
||||
},
|
||||
Span::new(last.0.start, pos),
|
||||
offset,
|
||||
false,
|
||||
options.match_algorithm,
|
||||
|
@ -101,14 +101,8 @@ impl NuCompleter {
|
||||
Ok(pd) => {
|
||||
let value = pd.into_value(span);
|
||||
if let Value::List { vals, span: _ } = value {
|
||||
let result = map_value_completions(
|
||||
vals.iter(),
|
||||
Span {
|
||||
start: span.start,
|
||||
end: span.end,
|
||||
},
|
||||
offset,
|
||||
);
|
||||
let result =
|
||||
map_value_completions(vals.iter(), Span::new(span.start, span.end), offset);
|
||||
|
||||
return Some(result);
|
||||
}
|
||||
@ -165,15 +159,12 @@ impl NuCompleter {
|
||||
|
||||
// Create a new span
|
||||
let new_span = if flat_idx == 0 {
|
||||
Span {
|
||||
start: flat.0.start,
|
||||
end: flat.0.end - 1 - span_offset,
|
||||
}
|
||||
Span::new(flat.0.start, flat.0.end - 1 - span_offset)
|
||||
} else {
|
||||
Span {
|
||||
start: flat.0.start - span_offset,
|
||||
end: flat.0.end - 1 - span_offset,
|
||||
}
|
||||
Span::new(
|
||||
flat.0.start - span_offset,
|
||||
flat.0.end - 1 - span_offset,
|
||||
)
|
||||
};
|
||||
|
||||
// Parses the prefix. Completion should look up to the cursor position, not after.
|
||||
|
@ -52,13 +52,13 @@ impl Completer for CustomCompletion {
|
||||
head: span,
|
||||
arguments: vec![
|
||||
Argument::Positional(Expression {
|
||||
span: Span { start: 0, end: 0 },
|
||||
span: Span::unknown(),
|
||||
ty: Type::String,
|
||||
expr: Expr::String(self.line.clone()),
|
||||
custom_completion: None,
|
||||
}),
|
||||
Argument::Positional(Expression {
|
||||
span: Span { start: 0, end: 0 },
|
||||
span: Span::unknown(),
|
||||
ty: Type::Int,
|
||||
expr: Expr::Int(line_pos as i64),
|
||||
custom_completion: None,
|
||||
|
@ -111,10 +111,7 @@ impl Completer for VariableCompletion {
|
||||
&self.engine_state,
|
||||
&self.stack,
|
||||
nu_protocol::NU_VARIABLE_ID,
|
||||
nu_protocol::Span {
|
||||
start: current_span.start,
|
||||
end: current_span.end,
|
||||
},
|
||||
nu_protocol::Span::new(current_span.start, current_span.end),
|
||||
) {
|
||||
for suggestion in
|
||||
nested_suggestions(nuval, self.var_context.1.clone(), current_span)
|
||||
@ -134,13 +131,7 @@ impl Completer for VariableCompletion {
|
||||
// Completion other variable types
|
||||
if let Some(var_id) = var_id {
|
||||
// Extract the variable value from the stack
|
||||
let var = self.stack.get_var(
|
||||
var_id,
|
||||
Span {
|
||||
start: span.start,
|
||||
end: span.end,
|
||||
},
|
||||
);
|
||||
let var = self.stack.get_var(var_id, Span::new(span.start, span.end));
|
||||
|
||||
// If the value exists and it's of type Record
|
||||
if let Ok(value) = var {
|
||||
@ -281,7 +272,7 @@ fn recursive_value(val: Value, sublevels: Vec<Vec<u8>>) -> Value {
|
||||
|
||||
// Current sublevel value not found
|
||||
return Value::Nothing {
|
||||
span: Span { start: 0, end: 0 },
|
||||
span: Span::unknown(),
|
||||
};
|
||||
}
|
||||
_ => return val,
|
||||
|
@ -76,7 +76,7 @@ pub fn evaluate_repl(
|
||||
"CMD_DURATION_MS".into(),
|
||||
Value::String {
|
||||
val: "0823".to_string(),
|
||||
span: Span { start: 0, end: 0 },
|
||||
span: Span::unknown(),
|
||||
},
|
||||
);
|
||||
|
||||
@ -84,7 +84,7 @@ pub fn evaluate_repl(
|
||||
"LAST_EXIT_CODE".into(),
|
||||
Value::Int {
|
||||
val: 0,
|
||||
span: Span { start: 0, end: 0 },
|
||||
span: Span::unknown(),
|
||||
},
|
||||
);
|
||||
|
||||
@ -375,7 +375,7 @@ pub fn evaluate_repl(
|
||||
"OLDPWD".into(),
|
||||
Value::String {
|
||||
val: cwd.clone(),
|
||||
span: Span { start: 0, end: 0 },
|
||||
span: Span::unknown(),
|
||||
},
|
||||
);
|
||||
|
||||
@ -385,7 +385,7 @@ pub fn evaluate_repl(
|
||||
"PWD".into(),
|
||||
Value::String {
|
||||
val: path.clone(),
|
||||
span: Span { start: 0, end: 0 },
|
||||
span: Span::unknown(),
|
||||
},
|
||||
);
|
||||
let cwd = Value::String { val: cwd, span };
|
||||
@ -440,7 +440,7 @@ pub fn evaluate_repl(
|
||||
"CMD_DURATION_MS".into(),
|
||||
Value::String {
|
||||
val: format!("{}", cmd_duration.as_millis()),
|
||||
span: Span { start: 0, end: 0 },
|
||||
span: Span::unknown(),
|
||||
},
|
||||
);
|
||||
|
||||
@ -997,7 +997,7 @@ fn run_ansi_sequence(seq: &str) -> Result<(), ShellError> {
|
||||
return Err(ShellError::GenericError(
|
||||
"Error writing ansi sequence".into(),
|
||||
err.to_string(),
|
||||
Some(Span { start: 0, end: 0 }),
|
||||
Some(Span::unknown()),
|
||||
None,
|
||||
Vec::new(),
|
||||
));
|
||||
@ -1007,7 +1007,7 @@ fn run_ansi_sequence(seq: &str) -> Result<(), ShellError> {
|
||||
ShellError::GenericError(
|
||||
"Error flushing stdio".into(),
|
||||
e.to_string(),
|
||||
Some(Span { start: 0, end: 0 }),
|
||||
Some(Span::unknown()),
|
||||
None,
|
||||
Vec::new(),
|
||||
)
|
||||
|
@ -149,7 +149,7 @@ fn split_span_by_highlight_positions(
|
||||
for pos in highlight_positions {
|
||||
if start <= *pos && pos < &span.end {
|
||||
if start < *pos {
|
||||
result.push((Span { start, end: *pos }, false));
|
||||
result.push((Span::new(start, *pos), false));
|
||||
}
|
||||
let span_str = &line[pos - global_span_offset..span.end - global_span_offset];
|
||||
let end = span_str
|
||||
@ -157,18 +157,12 @@ fn split_span_by_highlight_positions(
|
||||
.next()
|
||||
.map(|c| pos + get_char_length(c))
|
||||
.unwrap_or(pos + 1);
|
||||
result.push((Span { start: *pos, end }, true));
|
||||
result.push((Span::new(*pos, end), true));
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
if start < span.end {
|
||||
result.push((
|
||||
Span {
|
||||
start,
|
||||
end: span.end,
|
||||
},
|
||||
false,
|
||||
));
|
||||
result.push((Span::new(start, span.end), false));
|
||||
}
|
||||
result
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ fn set_last_exit_code(stack: &mut Stack, exit_code: i64) {
|
||||
"LAST_EXIT_CODE".to_string(),
|
||||
Value::Int {
|
||||
val: exit_code,
|
||||
span: Span { start: 0, end: 0 },
|
||||
span: Span::unknown(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user