diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f9a07698..ec54c3538 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +**Fixes**: + +- Make sure to parse `PortablePdb` streams in the correct order. ([#760](https://github.com/getsentry/symbolic/pull/760)) + ## 11.1.0 **Features**: diff --git a/symbolic-debuginfo/tests/test_objects.rs b/symbolic-debuginfo/tests/test_objects.rs index dcfd3797c..a1fb70670 100644 --- a/symbolic-debuginfo/tests/test_objects.rs +++ b/symbolic-debuginfo/tests/test_objects.rs @@ -748,10 +748,9 @@ fn test_ppdb_has_sources() -> Result<(), Error> { assert_eq!(object.has_sources(), true); } { - // This is a special case with a broken file, see symbolic-ppdb tests. let view = ByteView::open(fixture("android/Sentry.Samples.Maui.pdb"))?; let object = Object::parse(&view)?; - assert_eq!(object.has_sources(), false); + assert_eq!(object.has_sources(), true); } Ok(()) } diff --git a/symbolic-ppdb/src/format/mod.rs b/symbolic-ppdb/src/format/mod.rs index b729f5199..6021304c7 100644 --- a/symbolic-ppdb/src/format/mod.rs +++ b/symbolic-ppdb/src/format/mod.rs @@ -231,6 +231,7 @@ impl<'data> PortablePdb<'data> { guid_stream: None, }; + let mut metadata_stream = None; for _ in 0..stream_count { let (header, after_header_buf) = raw::StreamHeader::ref_from_prefix(streams_buf) .ok_or(FormatErrorKind::InvalidStreamHeader)?; @@ -260,15 +261,8 @@ impl<'data> PortablePdb<'data> { match name { "#Pdb" => result.pdb_stream = Some(PdbStream::parse(stream_buf)?), - "#~" => { - result.metadata_stream = Some(MetadataStream::parse( - stream_buf, - result - .pdb_stream - .as_ref() - .map_or([0; 64], |s| s.referenced_table_sizes), - )?) - } + // Save the #~ stream for last; it definitely must be parsed after the #Pdb stream. + "#~" => metadata_stream = Some(stream_buf), "#Strings" => result.string_stream = Some(StringStream::new(stream_buf)), "#US" => result.us_stream = Some(UsStream::new(stream_buf)), "#Blob" => result.blob_stream = Some(BlobStream::new(stream_buf)), @@ -276,6 +270,17 @@ impl<'data> PortablePdb<'data> { _ => return Err(FormatErrorKind::UnknownStream.into()), } } + + if let Some(stream_buf) = metadata_stream { + result.metadata_stream = Some(MetadataStream::parse( + stream_buf, + result + .pdb_stream + .as_ref() + .map_or([0; 64], |s| s.referenced_table_sizes), + )?) + } + Ok(result) } diff --git a/symbolic-ppdb/tests/test_ppdb.rs b/symbolic-ppdb/tests/test_ppdb.rs index 1e5e6da47..9988bb7e1 100644 --- a/symbolic-ppdb/tests/test_ppdb.rs +++ b/symbolic-ppdb/tests/test_ppdb.rs @@ -75,16 +75,14 @@ fn test_embedded_sources_contents() { ); } -/// This is here to prevent regression. The following test PDB was built in sentry-dotnet MAUI -/// sample for net6.0-android and failed with: `InvalidCustomDebugInformationTag(0)` #[test] -fn test_embedded_sources_with_metadata_broken() { +fn test_embedded_sources_with_metadata_maui() { let buf = std::fs::read(fixture("android/Sentry.Samples.Maui.pdb")).unwrap(); let ppdb = PortablePdb::parse(&buf).unwrap(); let iter = ppdb.get_embedded_sources().unwrap(); let items = iter.collect::, _>>().unwrap(); - assert_eq!(items.len(), 0); + assert_eq!(items.len(), 5); } #[test]