diff options
| author | bors <bors@rust-lang.org> | 2016-12-16 00:52:35 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-12-16 00:52:35 +0000 |
| commit | 8ae904062b2700a797138d2b8274f2e141ea1e53 (patch) | |
| tree | 553d6d10c11789417c8dbf00727d3716644519f3 /src | |
| parent | 8f02c429ad3e2ad687a222d1daae2e04bb9bb876 (diff) | |
| parent | 7bc10545d635bc1f4a5632703823a6f18113df9c (diff) | |
| download | rust-8ae904062b2700a797138d2b8274f2e141ea1e53.tar.gz rust-8ae904062b2700a797138d2b8274f2e141ea1e53.zip | |
Auto merge of #38352 - bluss:unaligned-metadata, r=eddyb
Fix unaligned loads in librustc_metadata Creating a `&[u32]` from an `&[u8]` is not necessarily valid, and crashes on certain platforms if the data is not well aligned.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_metadata/index.rs | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/src/librustc_metadata/index.rs b/src/librustc_metadata/index.rs index 53e6988c756..5b52b268849 100644 --- a/src/librustc_metadata/index.rs +++ b/src/librustc_metadata/index.rs @@ -70,7 +70,7 @@ impl<'tcx> LazySeq<Index> { index, words.len()); - let position = u32::from_le(words[index]); + let position = u32::from_le(words[index].get()); if position == u32::MAX { debug!("Index::lookup: position=u32::MAX"); None @@ -84,7 +84,7 @@ impl<'tcx> LazySeq<Index> { bytes: &'a [u8]) -> impl Iterator<Item = (DefIndex, Lazy<Entry<'tcx>>)> + 'a { let words = &bytes_to_words(&bytes[self.position..])[..self.len]; - words.iter().enumerate().filter_map(|(index, &position)| { + words.iter().map(|word| word.get()).enumerate().filter_map(|(index, position)| { if position == u32::MAX { None } else { @@ -95,8 +95,16 @@ impl<'tcx> LazySeq<Index> { } } -fn bytes_to_words(b: &[u8]) -> &[u32] { - unsafe { slice::from_raw_parts(b.as_ptr() as *const u32, b.len() / 4) } +#[repr(packed)] +#[derive(Copy, Clone)] +struct Unaligned<T>(T); + +impl<T> Unaligned<T> { + fn get(self) -> T { self.0 } +} + +fn bytes_to_words(b: &[u8]) -> &[Unaligned<u32>] { + unsafe { slice::from_raw_parts(b.as_ptr() as *const Unaligned<u32>, b.len() / 4) } } fn words_to_bytes(w: &[u32]) -> &[u8] { |
