Skip to content

Commit 1e8a61f

Browse files
authored
Add a better error message (#66)
1 parent b7d3bd5 commit 1e8a61f

2 files changed

Lines changed: 35 additions & 5 deletions

File tree

src/hash_table.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use nom::{
55
number::complete::*,
66
};
77
use std::borrow::Cow;
8+
use std::mem::size_of;
89
use tracing::debug;
910

1011
#[derive(Copy, Clone, Debug)]
@@ -49,13 +50,15 @@ fn read_value(
4950
return Err(nom::Err::Failure(VerboseError { errors }));
5051
}
5152
if input.len() < data_len {
53+
tracing::trace!("{} < {}", input.len(), data_len);
5254
return Err(nom::Err::Failure(VerboseError::from_error_kind(
5355
&input[input.len()..],
5456
ErrorKind::Eof,
5557
)));
5658
}
5759
let mut result = vec![];
5860
let end_len = input.len() - data_len;
61+
tracing::trace!("input: {} end: {}", input.len(), end_len);
5962

6063
let expected_end = &input[data_len..];
6164
let mut last_hash = 0;
@@ -69,12 +72,22 @@ fn read_value(
6972
}
7073
// This is only available for versions > v1. But as rust won't be going backwards to legacy
7174
// versions it's a safe assumption.
75+
tracing::trace!("1. le_u64: {}", bytes.len());
7276
let (bytes, counts_len) = le_u64(bytes)?;
77+
tracing::trace!("Counts len: {}", counts_len);
7378
if bytes.len() <= end_len {
7479
break;
7580
}
7681
input = bytes;
82+
if size_of::<u64>().saturating_mul(counts_len as usize) > input.len() {
83+
let errors = vec![(
84+
input,
85+
VerboseErrorKind::Context("hash_table value count length exceeds length of input"),
86+
)];
87+
return Err(nom::Err::Failure(VerboseError { errors }));
88+
}
7789
for _ in 0..counts_len {
90+
// tracing::trace!("2. le_u64: {}", input.len());
7891
let (bytes, count) = le_u64(input)?;
7992
input = bytes;
8093
counts.push(count);
@@ -86,6 +99,7 @@ fn read_value(
8699

87100
// If the version is > v2 then there can also be value profiling data so lets try and parse
88101
// that now
102+
tracing::trace!("3. le_u32: {}", input.len());
89103
let (bytes, total_size) = le_u32(input)?;
90104
if bytes.len() <= end_len {
91105
break;
@@ -151,7 +165,11 @@ impl HashTable {
151165
mut num_entries: u64,
152166
) -> ParseResult<'a, u64> {
153167
let (bytes, num_items_in_bucket) = le_u16(input)?;
154-
debug!("Number of items in bucket: {}", num_items_in_bucket);
168+
debug!(
169+
"Number of items in bucket: {}, input remaining: {}",
170+
num_items_in_bucket,
171+
input.len()
172+
);
155173
let mut remaining = bytes;
156174
for _i in 0..num_items_in_bucket {
157175
let (bytes, _hash) = le_u64(remaining)?;

src/instrumentation_profile/mod.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::instrumentation_profile::indexed_profile::*;
22
use crate::instrumentation_profile::raw_profile::*;
33
use crate::instrumentation_profile::text_profile::*;
44
use crate::instrumentation_profile::types::*;
5-
use nom::{error::VerboseError, IResult};
5+
use nom::{error::VerboseError, Err, IResult};
66
use std::fs::File;
77
use std::io;
88
use std::io::prelude::*;
@@ -43,9 +43,21 @@ pub fn parse_bytes(data: &[u8]) -> io::Result<InstrumentationProfile> {
4343
"Unsupported instrumentation profile format",
4444
));
4545
};
46-
nom_res.map(|(_bytes, res)| res).map_err(|_e| {
47-
trace!("{}", _e);
48-
io::Error::new(io::ErrorKind::Other, "Parsing failed")
46+
nom_res.map(|(_bytes, res)| res).map_err(|e| {
47+
// trace!("{}", e);
48+
let verbose_error_message = |err: VerboseError<&[u8]>| {
49+
err.errors
50+
.iter()
51+
.map(|(_, x)| format!("{:?}", x))
52+
.collect::<Vec<String>>()
53+
.join(" ")
54+
};
55+
let error_message = match e {
56+
Err::Error(e) => format!("parser error: {}", verbose_error_message(e)),
57+
Err::Failure(e) => format!("parser failure: {}", verbose_error_message(e)),
58+
Err::Incomplete(_) => unreachable!("llvm_profparsers works on complete data"),
59+
};
60+
io::Error::new(io::ErrorKind::Other, error_message)
4961
})
5062
}
5163

0 commit comments

Comments
 (0)