Skip to content

Commit

Permalink
Improve sanitization of expressions received via --focus-on
Browse files Browse the repository at this point in the history
  • Loading branch information
regexident committed Oct 22, 2024
1 parent 9a0dc9b commit be07f72
Show file tree
Hide file tree
Showing 17 changed files with 73 additions and 41 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Please make sure to add your changes to the appropriate categories:

### Added

- n/a
- The `--focus-on` option now accepts expressions starting with `crate::…` (previously the crate's name had to be written out).

### Changed

Expand Down
13 changes: 9 additions & 4 deletions src/analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,14 +600,19 @@ pub(crate) fn parse_ast<N: syntax::AstNode>(text: &str) -> N {
node
}

pub(crate) fn parse_use_tree(path_expr: &str) -> ast::UseTree {
parse_ast(&format!("use {path_expr};"))
}

pub(crate) fn parse_path_expr(path_expr: &str) -> ast::Path {
parse_ast(path_expr)
}

pub(crate) fn use_tree_matches_item_path(use_tree: &ast::UseTree, item_path: &str) -> bool {
if item_path.is_empty() {
return false;
}
let node_path: ast::Path = {
let syntax = format!("use {item_path};");
parse_ast(&syntax)
};
let node_path: ast::Path = parse_path_expr(item_path);
use_tree_matches_path(use_tree, &node_path)
}

Expand Down
12 changes: 3 additions & 9 deletions src/command/dependencies/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,9 @@ impl<'a> Filter<'a> {

let mut graph = graph.clone();

let focus_on = self
.options
.focus_on
.as_ref()
.cloned()
.unwrap_or_else(|| self.krate.display_name(self.db).unwrap().to_string());

let syntax = format!("use {focus_on};");
let use_tree: ast::UseTree = analyzer::parse_ast(&syntax);
let crate_name = self.krate.display_name(self.db).unwrap().to_string();
let focus_on = self.options.focus_on.as_deref();
let use_tree: ast::UseTree = crate::utils::sanitized_use_tree(focus_on, &crate_name)?;

trace!("Searching for focus nodes in graph ...");

Expand Down
12 changes: 3 additions & 9 deletions src/command/structure/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,9 @@ impl<'a> Filter<'a> {
}

pub fn filter(&self, tree: &Tree<Node>) -> anyhow::Result<Tree<Node>> {
let focus_on = self
.options
.focus_on
.as_ref()
.cloned()
.unwrap_or_else(|| self.krate.display_name(self.db).unwrap().to_string());

let syntax = format!("use {focus_on};");
let use_tree: ast::UseTree = analyzer::parse_ast(&syntax);
let crate_name = self.krate.display_name(self.db).unwrap().to_string();
let focus_on = self.options.focus_on.as_deref();
let use_tree: ast::UseTree = crate::utils::sanitized_use_tree(focus_on, &crate_name)?;

let max_depth = self.options.max_depth.unwrap_or(usize::MAX);

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ pub(crate) mod colors;
pub(crate) mod graph;
pub(crate) mod item;
pub(crate) mod tree;
pub(crate) mod utils;
38 changes: 38 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use ra_ap_syntax::ast;

use anyhow::bail;

pub fn sanitized_use_tree(
focus_on: Option<&str>,
crate_name: &str,
) -> anyhow::Result<ast::UseTree> {
let mut path_expr = focus_on.unwrap_or(crate_name).to_owned();

// Trim leading `::` from `use` expression,
// expressions are implied to be absolute:
let double_colon_prefix = "::";
if path_expr.starts_with(double_colon_prefix) {
let range = 0..(double_colon_prefix.len() - 2);
path_expr.replace_range(range, "");
}

let crate_prefix = "crate::";
if path_expr.starts_with(crate_prefix) {
let range = 0..(crate_prefix.len() - 2);
path_expr.replace_range(range, crate_name);
}

for keyword in ["super", "self", "$crate"] {
let keyword_prefix = format!("{keyword}::");

if path_expr == keyword || path_expr.starts_with(&keyword_prefix) {
bail!("unexpected keyword `{keyword}` in `--focus-on` option");
}
}

Ok(crate::analyzer::parse_use_tree(&path_expr))
}
8 changes: 4 additions & 4 deletions tests/dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ mod focus_on {
mod simple_path {
test_cmd!(
args: "dependencies \
--focus-on \"smoke::visibility::dummy\"",
--focus-on \"crate::visibility::dummy\"",
success: true,
color_mode: ColorMode::Plain,
project: smoke
Expand All @@ -396,7 +396,7 @@ mod focus_on {
mod glob_path {
test_cmd!(
args: "dependencies \
--focus-on \"smoke::visibility::*\"",
--focus-on \"crate::visibility::*\"",
success: true,
color_mode: ColorMode::Plain,
project: smoke
Expand All @@ -406,7 +406,7 @@ mod focus_on {
mod self_path {
test_cmd!(
args: "dependencies \
--focus-on \"smoke::visibility::dummy::{self}\"",
--focus-on \"crate::visibility::dummy::{self}\"",
success: true,
color_mode: ColorMode::Plain,
project: smoke
Expand All @@ -416,7 +416,7 @@ mod focus_on {
mod use_tree {
test_cmd!(
args: "dependencies \
--focus-on \"smoke::visibility::{dummy, hierarchy}\"",
--focus-on \"crate::visibility::{dummy, hierarchy}\"",
success: true,
color_mode: ColorMode::Plain,
project: smoke
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ expression: output
COMMAND:
dependencies
--focus-on
smoke::visibility::*
crate::visibility::*

STDERR:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ expression: output
COMMAND:
dependencies
--focus-on
smoke::visibility::dummy::{self}
crate::visibility::dummy::{self}

STDERR:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ expression: output
COMMAND:
dependencies
--focus-on
smoke::visibility::dummy
crate::visibility::dummy

STDERR:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ expression: output
COMMAND:
dependencies
--focus-on
smoke::visibility::{dummy, hierarchy}
crate::visibility::{dummy, hierarchy}

STDERR:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ expression: output
COMMAND:
structure
--focus-on
smoke_structure::lorem::sit::*
crate::lorem::sit::*

STDERR:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ expression: output
COMMAND:
structure
--focus-on
smoke_structure::lorem::sit::{self}
crate::lorem::sit::{self}

STDERR:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ expression: output
COMMAND:
structure
--focus-on
smoke_structure::lorem::sit
crate::lorem::sit

STDERR:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ expression: output
COMMAND:
structure
--focus-on
smoke_structure::{lorem::sit::ipsum, sit::dolor::amet::lorem::sit}
crate::{lorem::sit::ipsum, sit::dolor::amet::lorem::sit}

STDERR:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ expression: output
COMMAND:
structure
--focus-on
smoke_structure::{lorem, sit}
crate::{lorem, sit}
--max-depth
2

Expand Down
10 changes: 5 additions & 5 deletions tests/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ mod focus_on {
mod simple_path {
test_cmd!(
args: "structure \
--focus-on \"smoke_structure::lorem::sit\"",
--focus-on \"crate::lorem::sit\"",
success: true,
color_mode: ColorMode::Plain,
project: smoke_structure
Expand All @@ -356,7 +356,7 @@ mod focus_on {
mod glob_path {
test_cmd!(
args: "structure \
--focus-on \"smoke_structure::lorem::sit::*\"",
--focus-on \"crate::lorem::sit::*\"",
success: true,
color_mode: ColorMode::Plain,
project: smoke_structure
Expand All @@ -366,7 +366,7 @@ mod focus_on {
mod self_path {
test_cmd!(
args: "structure \
--focus-on \"smoke_structure::lorem::sit::{self}\"",
--focus-on \"crate::lorem::sit::{self}\"",
success: true,
color_mode: ColorMode::Plain,
project: smoke_structure
Expand All @@ -376,7 +376,7 @@ mod focus_on {
mod use_tree {
test_cmd!(
args: "structure \
--focus-on \"smoke_structure::{lorem::sit::ipsum, sit::dolor::amet::lorem::sit}\"",
--focus-on \"crate::{lorem::sit::ipsum, sit::dolor::amet::lorem::sit}\"",
success: true,
color_mode: ColorMode::Plain,
project: smoke_structure
Expand All @@ -386,7 +386,7 @@ mod focus_on {
mod with_max_depth {
test_cmd!(
args: "structure \
--focus-on \"smoke_structure::{lorem, sit}\" \
--focus-on \"crate::{lorem, sit}\" \
--max-depth 2",
success: true,
color_mode: ColorMode::Plain,
Expand Down

0 comments on commit be07f72

Please sign in to comment.