Skip to content

Commit b5ad302

Browse files
committed
auto merge of #12645 : alexcrichton/rust/invalid-libraries, r=brson
When the metadata format changes, old libraries often cause librustc to abort when reading their metadata. This should all change with the introduction of SVH markers, but the loader for crates should gracefully handle libraries without SVH markers still. This commit adds support for tripping fewer assertions when loading libraries by using maybe_get_doc when initially parsing metadata. It's still possible for some libraries to fall through the cracks, but this should deal with a fairly large number of them up front.
2 parents c81b3fb + 997ff7a commit b5ad302

File tree

4 files changed

+42
-4
lines changed

4 files changed

+42
-4
lines changed

src/librustc/metadata/decoder.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1145,12 +1145,26 @@ fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
11451145
Ok(())
11461146
}
11471147

1148+
pub fn maybe_get_crate_hash(data: &[u8]) -> Option<Svh> {
1149+
let cratedoc = reader::Doc(data);
1150+
reader::maybe_get_doc(cratedoc, tag_crate_hash).map(|doc| {
1151+
Svh::new(doc.as_str_slice())
1152+
})
1153+
}
1154+
11481155
pub fn get_crate_hash(data: &[u8]) -> Svh {
11491156
let cratedoc = reader::Doc(data);
11501157
let hashdoc = reader::get_doc(cratedoc, tag_crate_hash);
11511158
Svh::new(hashdoc.as_str_slice())
11521159
}
11531160

1161+
pub fn maybe_get_crate_id(data: &[u8]) -> Option<CrateId> {
1162+
let cratedoc = reader::Doc(data);
1163+
reader::maybe_get_doc(cratedoc, tag_crate_crateid).map(|doc| {
1164+
from_str(doc.as_str_slice()).unwrap()
1165+
})
1166+
}
1167+
11541168
pub fn get_crate_id(data: &[u8]) -> CrateId {
11551169
let cratedoc = reader::Doc(data);
11561170
let hashdoc = reader::get_doc(cratedoc, tag_crate_crateid);

src/librustc/metadata/loader.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -318,12 +318,17 @@ impl<'a> Context<'a> {
318318
}
319319

320320
fn crate_matches(&mut self, crate_data: &[u8]) -> bool {
321-
let other_id = decoder::get_crate_id(crate_data);
322-
if !self.crate_id.matches(&other_id) { return false }
321+
match decoder::maybe_get_crate_id(crate_data) {
322+
Some(ref id) if self.crate_id.matches(id) => {}
323+
_ => return false
324+
}
325+
let hash = match decoder::maybe_get_crate_hash(crate_data) {
326+
Some(hash) => hash, None => return false
327+
};
323328
match self.hash {
324329
None => true,
325-
Some(hash) => {
326-
if *hash != decoder::get_crate_hash(crate_data) {
330+
Some(myhash) => {
331+
if *myhash != hash {
327332
self.rejected_via_hash = true;
328333
false
329334
} else {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-include ../tools.mk
2+
3+
all:
4+
touch $(TMPDIR)/rust.metadata.bin
5+
ar crus $(TMPDIR)/libfoo-ffffffff-1.0.rlib $(TMPDIR)/rust.metadata.bin
6+
$(RUSTC) foo.rs 2>&1 | grep "can't find crate for"
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
extern crate foo;
12+
13+
fn main() {}

0 commit comments

Comments
 (0)