Skip to content

Commit e6af1ca

Browse files
committed
Add support for v6 macro metadata format
1 parent db2a708 commit e6af1ca

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

crates/proc_macro_api/src/version.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ fn read_section<'a>(dylib_binary: &'a [u8], section_name: &str) -> io::Result<&'
9999
/// * [length byte] next 1 byte tells us how many bytes we should read next
100100
/// for the version string's utf8 bytes
101101
/// * [version string bytes encoded in utf8] <- GET THIS BOI
102-
/// * [some more bytes that we don really care but still there] :-)
102+
/// * [some more bytes that we don't really care but about still there] :-)
103103
/// Check this issue for more about the bytes layout:
104104
/// <https://github.com/rust-analyzer/rust-analyzer/issues/6174>
105105
fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
@@ -108,15 +108,25 @@ fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
108108

109109
let dot_rustc = read_section(&dylib_mmaped, ".rustc")?;
110110

111-
let header = &dot_rustc[..8];
112-
const EXPECTED_HEADER: [u8; 8] = [b'r', b'u', b's', b't', 0, 0, 0, 5];
113-
// check if header is valid
114-
if header != EXPECTED_HEADER {
111+
// check if magic is valid
112+
if &dot_rustc[0..4] != b"rust" {
115113
return Err(io::Error::new(
116114
io::ErrorKind::InvalidData,
117-
format!("only metadata version 5 is supported, section header was: {:?}", header),
115+
format!("unknown metadata magic, expected `rust`, found `{:?}`", &dot_rustc[0..4]),
118116
));
119117
}
118+
let version = u32::from_be_bytes([dot_rustc[4], dot_rustc[5], dot_rustc[6], dot_rustc[7]]);
119+
// Last supported version is:
120+
// https://github.com/rust-lang/rust/commit/0696e79f2740ad89309269b460579e548a5cd632
121+
match version {
122+
5 | 6 => {}
123+
_ => {
124+
return Err(io::Error::new(
125+
io::ErrorKind::InvalidData,
126+
format!("unsupported metadata version {}", version),
127+
));
128+
}
129+
}
120130

121131
let snappy_portion = &dot_rustc[8..];
122132

@@ -130,7 +140,7 @@ fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
130140
// to know the length
131141
let mut bytes_before_version = [0u8; 13];
132142
snappy_decoder.read_exact(&mut bytes_before_version)?;
133-
let length = bytes_before_version[12]; // what? can't use -1 indexing?
143+
let length = bytes_before_version[12];
134144

135145
let mut version_string_utf8 = vec![0u8; length as usize];
136146
snappy_decoder.read_exact(&mut version_string_utf8)?;

0 commit comments

Comments
 (0)