about summary refs log tree commit diff
diff options
context:
space:
mode:
-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() {}