Skip to content

Commit 4ea1413

Browse files
sinescodeclaude
andcommitted
v0.4.2: trim whitespace from extracted usernames and passwords
Input lines with spaces around the divider (e.g. URL : email : pass) were producing output with leading/trailing whitespace and spaces around the colon. Added trim_ascii() to clean both user and pass parts, and handle the 2-part email@domain:pass format. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent eae10ea commit 4ea1413

4 files changed

Lines changed: 41 additions & 8 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ulpExtractor"
3-
version = "0.4.1"
3+
version = "0.4.2"
44
edition = "2021"
55

66
[dependencies]

src/extractor.rs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,25 @@ fn domain_end(user_part: &[u8], domain: &[u8]) -> Option<usize> {
6666
None
6767
}
6868

69+
/// Trim ASCII whitespace from both ends of a byte slice.
70+
fn trim_ascii(mut bytes: &[u8]) -> &[u8] {
71+
while let Some((first, rest)) = bytes.split_first() {
72+
if first.is_ascii_whitespace() {
73+
bytes = rest;
74+
} else {
75+
break;
76+
}
77+
}
78+
while let Some((last, rest)) = bytes.split_last() {
79+
if last.is_ascii_whitespace() {
80+
bytes = rest;
81+
} else {
82+
break;
83+
}
84+
}
85+
bytes
86+
}
87+
6988
pub fn find_files(dir: &Path, extensions: &[String], recursive: bool) -> std::io::Result<Vec<PathBuf>> {
7089
let exts: Vec<String> = extensions
7190
.iter()
@@ -241,12 +260,26 @@ pub fn extract_multi(
241260
let user_part = &line[..div_pos];
242261
if let Some(end_pos) = domain_end(user_part, domain) {
243262
let after = &user_part[end_pos..];
244-
// must have user portion: url:user:pass (at least 3 parts)
245263
if let Some(last_colon) = memrchr(div, after) {
246-
let mut out = after[last_colon + 1..].to_vec();
247-
out.push(div);
248-
out.extend_from_slice(&line[div_pos + 1..]);
249-
local.push(out);
264+
// 3-part: url/domain:user:pass
265+
let user = trim_ascii(&after[last_colon + 1..]);
266+
let pass = trim_ascii(&line[div_pos + 1..]);
267+
if !user.is_empty() && !pass.is_empty() {
268+
let mut out = user.to_vec();
269+
out.push(div);
270+
out.extend_from_slice(pass);
271+
local.push(out);
272+
}
273+
} else {
274+
// 2-part: email@domain:pass or domain.com:pass
275+
let user = trim_ascii(user_part);
276+
let pass = trim_ascii(&line[div_pos + 1..]);
277+
if !user.is_empty() && !pass.is_empty() {
278+
let mut out = user.to_vec();
279+
out.push(div);
280+
out.extend_from_slice(pass);
281+
local.push(out);
282+
}
250283
}
251284
}
252285
}

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ fn print_header() {
6969
let top = "┌".to_string() + &"─".repeat(w.saturating_sub(2)) + "┐";
7070
let bot = "└".to_string() + &"─".repeat(w.saturating_sub(2)) + "┘";
7171

72-
let title = " ulpExtractor v0.4.1 ";
72+
let title = " ulpExtractor v0.4.2 ";
7373
let subtitle = " Domain credential extractor ";
7474

7575
let pad = (w.saturating_sub(title.len())) / 2;

0 commit comments

Comments
 (0)