about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-03-02 00:26:26 -0800
committerbors <bors@rust-lang.org>2014-03-02 00:26:26 -0800
commitb5ad3022da9d4cea11ce3ddbce953edcc6e0eae9 (patch)
treeeee3a144e29395864a229150733a325dab21dca8
parentc81b3fb21a560f9eaacc06ceeabcd5b4339e54d0 (diff)
parent997ff7abd4f3b803575a7bfa4af3fb05569b1f75 (diff)
downloadrust-b5ad3022da9d4cea11ce3ddbce953edcc6e0eae9.tar.gz
rust-b5ad3022da9d4cea11ce3ddbce953edcc6e0eae9.zip
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.
-rw-r--r--src/librustc/metadata/decoder.rs14
-rw-r--r--src/librustc/metadata/loader.rs13
-rw-r--r--src/test/run-make/invalid-library/Makefile6
-rw-r--r--src/test/run-make/invalid-library/foo.rs13
4 files changed, 42 insertions, 4 deletions
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 42754aedba7..8cfda93bd84 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -1145,12 +1145,26 @@ fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
     Ok(())
 }
 
+pub fn maybe_get_crate_hash(data: &[u8]) -> Option<Svh> {
+    let cratedoc = reader::Doc(data);
+    reader::maybe_get_doc(cratedoc, tag_crate_hash).map(|doc| {
+        Svh::new(doc.as_str_slice())
+    })
+}
+
 pub fn get_crate_hash(data: &[u8]) -> Svh {
     let cratedoc = reader::Doc(data);
     let hashdoc = reader::get_doc(cratedoc, tag_crate_hash);
     Svh::new(hashdoc.as_str_slice())
 }
 
+pub fn maybe_get_crate_id(data: &[u8]) -> Option<CrateId> {
+    let cratedoc = reader::Doc(data);
+    reader::maybe_get_doc(cratedoc, tag_crate_crateid).map(|doc| {
+        from_str(doc.as_str_slice()).unwrap()
+    })
+}
+
 pub fn get_crate_id(data: &[u8]) -> CrateId {
     let cratedoc = reader::Doc(data);
     let hashdoc = reader::get_doc(cratedoc, tag_crate_crateid);
diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs
index 9c61191ff99..617a8654eed 100644
--- a/src/librustc/metadata/loader.rs
+++ b/src/librustc/metadata/loader.rs
@@ -318,12 +318,17 @@ impl<'a> Context<'a> {
     }
 
     fn crate_matches(&mut self, crate_data: &[u8]) -> bool {
-        let other_id = decoder::get_crate_id(crate_data);
-        if !self.crate_id.matches(&other_id) { return false }
+        match decoder::maybe_get_crate_id(crate_data) {
+            Some(ref id) if self.crate_id.matches(id) => {}
+            _ => return false
+        }
+        let hash = match decoder::maybe_get_crate_hash(crate_data) {
+            Some(hash) => hash, None => return false
+        };
         match self.hash {
             None => true,
-            Some(hash) => {
-                if *hash != decoder::get_crate_hash(crate_data) {
+            Some(myhash) => {
+                if *myhash != hash {
                     self.rejected_via_hash = true;
                     false
                 } else {
diff --git a/src/test/run-make/invalid-library/Makefile b/src/test/run-make/invalid-library/Makefile
new file mode 100644
index 00000000000..0dbe655b77d
--- /dev/null
+++ b/src/test/run-make/invalid-library/Makefile
@@ -0,0 +1,6 @@
+-include ../tools.mk
+
+all:
+	touch $(TMPDIR)/rust.metadata.bin
+	ar crus $(TMPDIR)/libfoo-ffffffff-1.0.rlib $(TMPDIR)/rust.metadata.bin
+	$(RUSTC) foo.rs 2>&1 | grep "can't find crate for"
diff --git a/src/test/run-make/invalid-library/foo.rs b/src/test/run-make/invalid-library/foo.rs
new file mode 100644
index 00000000000..6316cfa3bba
--- /dev/null
+++ b/src/test/run-make/invalid-library/foo.rs
@@ -0,0 +1,13 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate foo;
+
+fn main() {}