Skip to content

Commit

Permalink
Corrects /proc/pid/maps parser to correctly handle spaces in pathnames
Browse files Browse the repository at this point in the history
  • Loading branch information
MasonRemaley committed Jul 24, 2023
1 parent 0533d47 commit 6294cb5
Showing 1 changed file with 54 additions and 9 deletions.
63 changes: 54 additions & 9 deletions src/symbolize/gimli/parse_running_mmaps_unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 85,47 @@ impl FromStr for MapsEntry {
// e.g.: "ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]"
// e.g.: "7f5985f46000-7f5985f48000 rw-p 00039500 103:06 76021795 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2"
// e.g.: "35b1a21000-35b1a22000 rw-p 00000000 00:00 0"
//
// Note that paths may contain spaces, so we can't use `str::split` for parsing (until
// Split::remainder is stabalized #77998).
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut parts = s
.split(' ') // space-separated fields
.filter(|s| s.len() > 0); // multiple spaces implies empty strings that need to be skipped.
let range_str = parts.next().ok_or("Couldn't find address")?;
let perms_str = parts.next().ok_or("Couldn't find permissions")?;
let offset_str = parts.next().ok_or("Couldn't find offset")?;
let dev_str = parts.next().ok_or("Couldn't find dev")?;
let inode_str = parts.next().ok_or("Couldn't find inode")?;
let pathname_str = parts.next().unwrap_or(""); // pathname may be omitted.
let (range_str, s) = s.trim()
.split_once(' ')
.unwrap_or((s, ""));
if range_str.is_empty() {
return Err("Couldn't find address");
}

let (perms_str, s) = s.trim()
.split_once(' ')
.unwrap_or((s, ""));
if range_str.is_empty() {
return Err("Couldn't find permissions");
}

let (offset_str, s) = s.trim()
.split_once(' ')
.unwrap_or((s, ""));
if range_str.is_empty() {
return Err("Couldn't find offset");
}

let (dev_str, s) = s.trim()
.split_once(' ')
.unwrap_or((s, ""));
if range_str.is_empty() {
return Err("Couldn't find dev");
}

let (inode_str, s) = s.trim()
.split_once(' ')
.unwrap_or((s, ""));
if range_str.is_empty() {
return Err("Couldn't find inode");
}

// Pathname may be omitted in which case it will be empty
let pathname_str = s.trim();

let hex = |s| usize::from_str_radix(s, 16).map_err(|_| "Couldn't parse hex number");
let address = if let Some((start, limit)) = range_str.split_once('-') {
Expand Down Expand Up @@ -229,4 260,18 @@ fn check_maps_entry_parsing_32bit() {
pathname: Default::default(),
}
);
assert_eq!(
"b7c79500-b7e02000 r--p 00000000 08:01 60662705 \
/executable/path/with some spaces"
.parse::<MapsEntry>()
.unwrap(),
MapsEntry {
address: (0xb7c79500, 0xb7e02000),
perms: ['r', '-', '-', 'p'],
offset: 0x00000000,
dev: (0x08, 0x01),
inode: 0x60662705,
pathname: "/executable/path/with some spaces".into(),
}
);
}

0 comments on commit 6294cb5

Please sign in to comment.