about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRune Tynan <runetynan@gmail.com>2023-02-13 12:50:45 -0500
committerRune Tynan <runetynan@gmail.com>2023-02-20 13:38:16 -0500
commitdce3947110a73efebb756242d5c775a3ddad32a9 (patch)
tree2de9fe1d7f5276f3f8d174e7b370a168510ccd80
parent267cd1d2c5abf5f0d825822a4179ba807b69ffb4 (diff)
downloadrust-dce3947110a73efebb756242d5c775a3ddad32a9.tar.gz
rust-dce3947110a73efebb756242d5c775a3ddad32a9.zip
Try adding metadata length prefix, and obey it while decoding
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs1
-rw-r--r--compiler/rustc_metadata/src/locator.rs9
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs2
3 files changed, 10 insertions, 2 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 7d3c14fec5f..190cd69a0e9 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -305,6 +305,7 @@ pub fn create_compressed_metadata_file(
     symbol_name: &str,
 ) -> Vec<u8> {
     let mut compressed = rustc_metadata::METADATA_HEADER.to_vec();
+    compressed.write_all(&(metadata.raw_data().len() as u32).to_be_bytes()).unwrap();
     FrameEncoder::new(&mut compressed).write_all(metadata.raw_data()).unwrap();
     let Some(mut file) = create_object_file(sess) else {
         return compressed.to_vec();
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 755a2425350..285d6e22d47 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -798,8 +798,15 @@ fn get_metadata_section<'p>(
                 )));
             }
 
+            // Length of the compressed stream - this allows linkers to pad the section if they want
+            let usize_len = core::mem::size_of::<u32>();
+            let Ok(len_bytes) = <[u8; 4]>::try_from(&buf[header_len..cmp::min(header_len + usize_len, buf.len())]) else {
+                return Err(MetadataError::LoadFailure("invalid metadata length found".to_string()));
+            };
+            let compressed_len = u32::from_be_bytes(len_bytes) as usize;
+
             // Header is okay -> inflate the actual metadata
-            let compressed_bytes = &buf[header_len..];
+            let compressed_bytes = &buf[header_len..compressed_len + header_len];
             debug!("inflating {} bytes of compressed metadata", compressed_bytes.len());
             // Assume the decompressed data will be at least the size of the compressed data, so we
             // don't have to grow the buffer as much.
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 01691398ad0..9ed4d241bd0 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -55,7 +55,7 @@ pub(crate) fn rustc_version() -> String {
 /// Metadata encoding version.
 /// N.B., increment this if you change the format of metadata such that
 /// the rustc version can't be found to compare with `rustc_version()`.
-const METADATA_VERSION: u8 = 6;
+const METADATA_VERSION: u8 = 7;
 
 /// Metadata header which includes `METADATA_VERSION`.
 ///