diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 7d3c14fec5fb..190cd69a0e9c 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 { 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 755a24253504..285d6e22d47d 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::(); + 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 01691398ad08..9ed4d241bd03 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`. ///