Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
`LOOPBACK | UP`.
- `errno` updated from 0.2 to 0.3. `Error::ErrnoError` carries an `errno::Errno`, so crates that
construct or match on it have to move to 0.3 as well.
- Error messages coming from libpcap are decoded lossily. libpcap truncates them at
`PCAP_ERRBUF_SIZE` without regard for character boundaries, so one quoting a long non-ASCII
path used to arrive as `Error::MalformedError` with the message thrown away. It now arrives as
`Error::PcapError`. Device and link-layer type names are still rejected when malformed.
- `windows-sys` updated from 0.36 to 0.61. `HANDLE` is a raw pointer there rather than an `isize`,
which changes the signature of `Capture::get_event` on Windows. A raw pointer is not `Send`, so
a type of your own that stores the returned `HANDLE` no longer derives `Send` and can no longer
Expand Down
18 changes: 14 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,19 @@ pub enum Error {

impl Error {
unsafe fn new(ptr: *const libc::c_char) -> Error {
match unsafe { cstr_to_string(ptr) } {
Err(e) => e as Error,
Ok(string) => PcapError(string.unwrap_or_default()),
if ptr.is_null() {
return PcapError(String::new());
}

// libpcap truncates its messages at PCAP_ERRBUF_SIZE without regard for character
// boundaries, so one quoting a long path can end in the middle of a UTF-8 sequence.
// Take such a message lossily rather than lose it. Strings that are not error messages
// still go through cstr_to_string, which rejects the malformed ones.
PcapError(
unsafe { CStr::from_ptr(ptr as _) }
.to_string_lossy()
.into_owned(),
)
}

fn with_errbuf<T, F>(func: F) -> Result<T, Error>
Expand Down Expand Up @@ -252,7 +261,8 @@ mod tests {
fn test_error_invalid_utf8() {
let bytes: [u8; 8] = [0x78, 0xfe, 0xe9, 0x89, 0x00, 0x00, 0xed, 0x4f];
let error = unsafe { Error::new(&bytes as *const _ as _) };
assert!(matches!(error, Error::MalformedError(_)));
// The message is kept, with the bytes that are not valid UTF-8 replaced.
assert_eq!(error, Error::PcapError("x\u{fffd}\u{fffd}".to_string()));
}

#[test]
Expand Down
7 changes: 7 additions & 0 deletions src/linktype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,13 @@ mod tests {

let linktype_name = Linktype::ARCNET_LINUX.get_name().unwrap();
assert_eq!(&linktype_name, name);

let ctx = raw::pcap_datalink_val_to_name_context();
ctx.checkpoint();
ctx.expect().return_once(|_| std::ptr::null());

let err = Linktype::ARCNET_LINUX.get_name().unwrap_err();
assert_eq!(err, Error::InvalidLinktype);
}

#[test]
Expand Down
Loading