Skip to content

Commit a1ad6ca

Browse files
committed
Detect truncated incr comp files
1 parent 4282576 commit a1ad6ca

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

compiler/rustc_incremental/src/persist/file_format.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ use rustc_session::Session;
1717
use std::borrow::Cow;
1818
use std::env;
1919
use std::fs;
20-
use std::io::{self, Read};
20+
use std::io::{self, Read, Write};
2121
use std::path::{Path, PathBuf};
22+
use std::io::{Seek, SeekFrom};
2223

2324
/// The first few bytes of files generated by incremental compilation.
2425
const FILE_MAGIC: &[u8] = b"RSIC";
@@ -35,6 +36,8 @@ pub(crate) fn write_file_header(stream: &mut FileEncoder, sess: &Session) {
3536
assert_eq!(rustc_version.len(), (rustc_version.len() as u8) as usize);
3637
stream.emit_raw_bytes(&[rustc_version.len() as u8]);
3738
stream.emit_raw_bytes(rustc_version.as_bytes());
39+
// Reserve space for the u64 where we will later write in the expected total size of this file.
40+
stream.emit_raw_bytes(&0u64.to_le_bytes());
3841
}
3942

4043
pub(crate) fn save_in<F>(sess: &Session, path_buf: PathBuf, name: &str, encode: F)
@@ -65,6 +68,8 @@ where
6568

6669
write_file_header(&mut encoder, sess);
6770

71+
let len_offset = encoder.position() - 8;
72+
6873
match encode(encoder) {
6974
Ok(position) => {
7075
sess.prof.artifact_size(
@@ -76,6 +81,17 @@ where
7681
}
7782
Err((path, err)) => sess.dcx().emit_fatal(errors::WriteNew { name, path, err }),
7883
}
84+
85+
if let Err(err) = write_file_len(&path_buf, len_offset as u64) {
86+
sess.dcx().emit_fatal(errors::WriteNew { name, path: path_buf, err });
87+
}
88+
}
89+
90+
fn write_file_len(path: &Path, offset: u64) -> Result<(), std::io::Error> {
91+
let mut file = fs::File::options().write(true).create(false).open(path)?;
92+
let len = file.metadata()?.len();
93+
file.seek(SeekFrom::Start(offset))?;
94+
file.write_all(&len.to_le_bytes())
7995
}
8096

8197
/// Reads the contents of a file with a file header as defined in this module.
@@ -147,6 +163,14 @@ pub fn read_file(
147163
}
148164
}
149165

166+
// Check FILE_LEN
167+
{
168+
let mut len = [0u8; 8];
169+
file.read_exact(&mut len)?;
170+
let len_in_header = u64::from_le_bytes(len);
171+
assert_eq!(len_in_header, fs::metadata(path)?.len());
172+
}
173+
150174
let post_header_start_pos = file.position() as usize;
151175
Ok(Some((mmap, post_header_start_pos)))
152176
}

0 commit comments

Comments
 (0)