Skip to content

Commit

Permalink
Nicer display of ranges in the filters table
Browse files Browse the repository at this point in the history
  • Loading branch information
cestef committed Apr 17, 2024
1 parent c3bc9a9 commit 44ae67e
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 43 deletions.
3 changes: 3 additions & 0 deletions .justfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ default:
run *ARGS="":
cargo run --quiet -- {{ARGS}}

test:
cargo nextest run

# Build the program
build OUTPUT="./target/release":
cargo build --release -Z unstable-options --quiet --out-dir {{OUTPUT}}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub const PROGRESS_TEMPLATE: &str = "{spinner:.blue} (ETA. {eta}) [{wide_bar}] {
pub const PROGRESS_CHARS: &str = "█▉▊▋▌▍▎▏ ";

pub const DEFAULT_SAVE_FILE: &str = ".rwalk.json";
pub const DEFAULT_STATUS_CODES: &str = "200-299,301,302,307,401,403,405,500";
pub const DEFAULT_STATUS_CODES: &str = "200-299,301-302,307,401,403,405,500";
pub const DEFAULT_FUZZ_KEY: &str = "$";
pub const DEFAULT_FOLLOW_REDIRECTS: usize = 5;
pub const DEFAULT_TIMEOUT: usize = 10;
Expand Down
51 changes: 51 additions & 0 deletions src/utils/display.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use super::color_for_status_code;
use colored::Colorize;

pub fn display_range_status(mut status: String) -> String {
if status.contains('-') {
status = status
.split('-')
.map(|x| match x.parse::<u16>() {
Ok(x) => color_for_status_code(x.to_string(), x),
Err(_) => x.to_string(),
})
.collect::<Vec<_>>()
.join("-")
.to_string();
} else if let Some(stripped) = status.strip_prefix('>') {
status = ">".to_string()
+ &color_for_status_code(stripped.to_string(), stripped.parse().unwrap_or_default());
} else if let Some(stripped) = status.strip_prefix('<') {
status = "<".to_string()
+ &color_for_status_code(stripped.to_string(), stripped.parse().unwrap_or_default());
} else {
status = color_for_status_code(status.to_string(), status.parse().unwrap_or_default());
}

status
}

pub fn display_range(range: String) -> String {
range
.split(',')
.map(|x| {
if let Some(stripped) = x.strip_prefix('>') {
">".to_string() + &stripped.blue().to_string()
} else if let Some(stripped) = x.strip_prefix('<') {
"<".to_string() + &stripped.blue().to_string()
} else {
let parts = x.split('-').collect::<Vec<_>>();
if parts.len() == 2 {
let start = parts[0].parse::<u16>().unwrap_or_default();
let end = parts[1].parse::<u16>().unwrap_or_default();
start.to_string().blue().to_string() + "-" + &end.to_string().blue().to_string()
} else if let Ok(x) = x.parse::<u16>() {
x.to_string().blue().to_string()
} else {
x.to_string()
}
}
})
.collect::<Vec<_>>()
.join(", ")
}
29 changes: 29 additions & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::utils::{
use self::constants::DEFAULT_FILE_TYPE;

pub mod constants;
pub mod display;
pub mod logger;
pub mod structs;
pub mod table;
Expand Down Expand Up @@ -111,6 +112,34 @@ pub fn parse_range_input(s: &str) -> Result<Vec<(usize, usize)>> {
Ok(ranges)
}

pub fn is_range(s: &str) -> bool {
for part in s.split(',') {
// >number, <number, number-number, number
if let Some(stripped) = part.strip_prefix('>') {
if stripped.parse::<usize>().is_ok() {
return true;
}
} else if let Some(stripped) = part.strip_prefix('<') {
if stripped.parse::<usize>().is_ok() {
return true;
}
} else {
let parts = part.split('-').collect::<Vec<_>>();
if parts.len() == 1 {
if parts[0].parse::<usize>().is_ok() {
return true;
}
} else if parts.len() == 2
&& parts[0].parse::<usize>().is_ok()
&& parts[1].parse::<usize>().is_ok()
{
return true;
}
}
}
false
}

// Write the tree to a file (json, csv, md)
pub fn save_to_file(
opts: &Opts,
Expand Down
100 changes: 59 additions & 41 deletions src/utils/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@ use crate::{
opts::Opts,
},
runner::wordlists::ParsedWordlist,
utils::{
display::{display_range, display_range_status},
is_range,
},
};
use colored::{Colorize, CustomColor};
use log::{info, warn};
use tabled::{
builder::Builder,
settings::{Alignment, Style},
};

use super::{
color_for_status_code,
structs::{FuzzMatch, Mode},
};
use super::structs::{FuzzMatch, Mode};

/// Builds the options table printed in the CLI
pub fn build_opts_table(
Expand All @@ -30,48 +32,64 @@ pub fn build_opts_table(
let mut builder = Builder::default();

let mut filters_builder = Builder::default();
filters_builder.push_record(vec!["Filter", "Value"]);
filters_builder.push_record(vec!["Depth", "Filter", "Value"]);
for filter in &opts.filter {
match filter {
KeyVal(k, v) if k == "status" => {
let mut out = String::new();
for status in v.split(',') {
let mut status = status.to_string();
if status.contains('-') {
status = status
.split('-')
.map(|x| match x.parse::<u16>() {
Ok(x) => color_for_status_code(x.to_string(), x),
Err(_) => x.to_string(),
})
.collect::<Vec<_>>()
.join("-")
.to_string();
} else if let Some(stripped) = status.strip_prefix('>') {
status = ">".to_string()
+ &color_for_status_code(
stripped.to_string(),
stripped.parse().unwrap_or_default(),
);
} else if let Some(stripped) = status.strip_prefix('<') {
status = "<".to_string()
+ &color_for_status_code(
stripped.to_string(),
stripped.parse().unwrap_or_default(),
);
match filter.clone() {
KeyVal(mut k, v) if k == "status" => {
let out = v
.split(',')
.map(|status| display_range_status(status.to_string()))
.collect::<Vec<_>>()
.join(", ");
let filter_depth = if k.starts_with('[') {
let start_index = k.find('[').unwrap();
let end_index = k.find(']').unwrap();
let depth = k[start_index + 1..end_index].parse::<usize>();
k = k[end_index + 1..].to_string();
if let Ok(d) = depth {
Some(d)
} else {
warn!("Invalid depth filter: {}", depth.unwrap_err());
None
}
} else {
None
};
filters_builder.push_record(vec![
filter_depth.map_or("*".to_string(), |x| x.to_string()),
k,
out.trim_end_matches(", ").to_string(),
]);
}
KeyVal(mut k, v) => {
let filter_depth = if k.starts_with('[') {
let start_index = k.find('[').unwrap();
let end_index = k.find(']').unwrap();
let depth = k[start_index + 1..end_index].parse::<usize>();
k = k[end_index + 1..].to_string();
if let Ok(d) = depth {
Some(d)
} else {
status = color_for_status_code(
status.to_string(),
status.parse().unwrap_or_default(),
);
warn!("Invalid depth filter: {}", depth.unwrap_err());
None
}
out.push_str(&status);
out.push_str(", ");
}
} else {
None
};
// Try to parse the value as a range
let is_range = is_range(&v);
let v = if is_range {
display_range(v.to_string())
} else {
v
};

filters_builder.push_record(vec![k, &out.trim_end_matches(", ").to_string()]);
filters_builder.push_record(vec![
filter_depth.map_or("*".to_string(), |x| x.to_string()),
k,
v,
]);
}
KeyVal(k, v) => filters_builder.push_record(vec![k, &v.bold().to_string()]),
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/utils/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ mod tests {
.unwrap();
assert_eq!(
String::from_utf8(buffer).unwrap(),
"✓ 200 /test".to_string()
"✓ 200 /test (dir)".to_string()
);
}
}

0 comments on commit 44ae67e

Please sign in to comment.