Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: PE embedded PPDB decompression to a custom writer #757

Merged
merged 3 commits into from
Feb 7, 2023
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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

- Correctly read the `debug_id` of Deterministic PE files ([#658](https://github.com/getsentry/symbolic/pull/658))
- Gracefully handle invalid PPDBs ([#751](https://github.com/getsentry/symbolic/pull/751))
- Support embedded PortablePDB in DLLs ([#752](https://github.com/getsentry/symbolic/pull/752))
- Support embedded PortablePDB in DLLs ([#752](https://github.com/getsentry/symbolic/pull/752), [#757](https://github.com/getsentry/symbolic/pull/757))

## 11.0.0

Expand Down
23 changes: 10 additions & 13 deletions symbolic-debuginfo/src/pe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
use std::borrow::Cow;
use std::error::Error;
use std::fmt;
use std::io::Read;
use std::io::Write;

use flate2::read::DeflateDecoder;
use gimli::RunTimeEndian;
use goblin::pe;
use scroll::{Pread, LE};
Expand Down Expand Up @@ -504,16 +503,14 @@ impl<'data, 'object> PeEmbeddedPortablePDB<'data> {
self.uncompressed_size
}

/// Reads the Portable PDB contents into the provided vector.
pub fn decompress(&self) -> Result<Vec<u8>, PeError> {
let mut decoder = DeflateDecoder::new(self.compressed_data);
let mut output: Vec<u8> = vec![0; self.uncompressed_size];
let read_size = decoder.read(&mut output).map_err(PeError::new)?;
if read_size != self.uncompressed_size {
return Err(PeError::new(symbolic_ppdb::FormatError::from(
symbolic_ppdb::FormatErrorKind::InvalidLength,
)));
}
Ok(output)
/// Reads the Portable PDB contents into the writer.
pub fn decompress_to<W: Write>(&self, output: W) -> Result<(), PeError> {
use std::io::prelude::*;
let mut decoder = flate2::write::DeflateDecoder::new(output);
decoder
.write_all(self.compressed_data)
.and_then(|_| decoder.finish())
.map_err(PeError::new)?;
Ok(())
}
}
10 changes: 8 additions & 2 deletions symbolic-debuginfo/tests/test_objects.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{ffi::CString, fmt};
use std::{env, ffi::CString, fmt, io::BufWriter};

use symbolic_common::ByteView;
use symbolic_debuginfo::{
Expand Down Expand Up @@ -565,8 +565,14 @@ fn test_pe_embedded_ppdb() -> Result<(), Error> {
let embedded_ppdb = pe.embedded_ppdb().unwrap().unwrap();
assert_eq!(embedded_ppdb.get_size(), 10540);

let buf = embedded_ppdb.decompress()?;
let mut buf = Vec::new();
embedded_ppdb.decompress_to(&mut buf)?;
assert_eq!(&buf[15..25], "\0PDB v1.0\0".as_bytes());

let tmp_file = tempfile::tempfile()?;
embedded_ppdb.decompress_to(BufWriter::new(&tmp_file))?;
let file_buf = ByteView::map_file(tmp_file)?;
assert_eq!(buf, file_buf.as_slice());
}
Ok(())
}
Expand Down
6 changes: 4 additions & 2 deletions symbolic-ppdb/tests/test_ppdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ fn test_pe_embedded_ppdb_without_sources() {
let pe = PeObject::parse(&pe_buf).unwrap();

let embedded_ppdb = pe.embedded_ppdb().unwrap().unwrap();
let ppdb_buf = embedded_ppdb.decompress().unwrap();
let mut ppdb_buf = Vec::new();
embedded_ppdb.decompress_to(&mut ppdb_buf).unwrap();
let ppdb = PortablePdb::parse(&ppdb_buf).unwrap();

assert_eq!(ppdb.pdb_id().unwrap(), pe.debug_id());
Expand All @@ -128,7 +129,8 @@ fn test_pe_embedded_ppdb_with_sources() {
let pe = PeObject::parse(&pe_buf).unwrap();

let embedded_ppdb = pe.embedded_ppdb().unwrap().unwrap();
let ppdb_buf = embedded_ppdb.decompress().unwrap();
let mut ppdb_buf = Vec::new();
embedded_ppdb.decompress_to(&mut ppdb_buf).unwrap();
let ppdb = PortablePdb::parse(&ppdb_buf).unwrap();

assert_eq!(ppdb.pdb_id().unwrap(), pe.debug_id());
Expand Down