about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-12-12 18:00:17 -0800
committerAlex Crichton <alex@alexcrichton.com>2014-12-12 18:02:01 -0800
commit9a47d65e3b71a86abd6e64c8f126cff2d6e80f92 (patch)
treefedea55954f0dd7bc98092b5660fc5a95cef3b2a
parentffc111889e93bcd38222d9d74a70fdc26a78fcb5 (diff)
downloadrust-9a47d65e3b71a86abd6e64c8f126cff2d6e80f92.tar.gz
rust-9a47d65e3b71a86abd6e64c8f126cff2d6e80f92.zip
rustc: Don't panic on corrupt metadata
Fix a panic where the compiler was looking at stale or old metadata.

See #19798, #19772, #19757, #19744, #19718, #19691.
-rw-r--r--src/librustc/metadata/cstore.rs16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs
index bb1c75b075c..976adaad93a 100644
--- a/src/librustc/metadata/cstore.rs
+++ b/src/librustc/metadata/cstore.rs
@@ -236,13 +236,17 @@ impl MetadataBlob {
             MetadataArchive(ref ar) => ar.as_slice(),
         };
         if slice.len() < 4 {
-            &[]
+            &[] // corrupt metadata
         } else {
-            let len = ((slice[0] as u32) << 24) |
-                      ((slice[1] as u32) << 16) |
-                      ((slice[2] as u32) << 8) |
-                      ((slice[3] as u32) << 0);
-            slice.slice(4, len as uint + 4)
+            let len = (((slice[0] as u32) << 24) |
+                       ((slice[1] as u32) << 16) |
+                       ((slice[2] as u32) << 8) |
+                       ((slice[3] as u32) << 0)) as uint;
+            if len + 4 <= slice.len() {
+                slice.slice(4, len + 4)
+            } else {
+                &[] // corrupt or old metadata
+            }
         }
     }
 }