add check for giant id bound
authorJacob Lifshay <programmerjake@gmail.com>
Wed, 31 Oct 2018 08:45:15 +0000 (01:45 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Wed, 31 Oct 2018 08:45:15 +0000 (01:45 -0700)
spirv-parser-generator/src/generate.rs

index 43c59cbd43caf106612ee7897aaa772752821a0b..c456c3c7c00ba54fba33fc5f7b2564575fe326ac 100644 (file)
@@ -1430,6 +1430,7 @@ pub(crate) fn generate(
                 pub enum Error {
                     MissingHeader,
                     InvalidHeader,
+                    BoundTooBig(u32),
                     UnsupportedVersion(u32, u32),
                     ZeroInstructionLength,
                     SourcePrematurelyEnded,
@@ -1467,6 +1468,11 @@ pub(crate) fn generate(
                         match *self {
                             Error::MissingHeader => write!(f, "SPIR-V source is missing the file header"),
                             Error::InvalidHeader => write!(f, "SPIR-V source has an invalid file header"),
+                            Error::BoundTooBig(bound) => write!(
+                                f,
+                                "SPIR-V source has an invalid file header; the id bound is way bigger than needed: {}",
+                                bound,
+                            ),
                             Error::UnsupportedVersion(major, minor) => write!(
                                 f,
                                 "SPIR-V source has an unsupported version: {}.{}",
@@ -1591,13 +1597,17 @@ pub(crate) fn generate(
                             }
                             _ => return Err(Error::InvalidHeader),
                         };
-                        Ok(Self {
-                            words,
-                            header,
-                            parse_state: ParseState {
-                                id_states: vec![IdState::Unknown; header.bound as usize],
-                            },
-                        })
+                        if header.bound as usize > words.len() && header.bound > 0x10000 {
+                            Err(Error::BoundTooBig(header.bound))
+                        } else {
+                            Ok(Self {
+                                words,
+                                header,
+                                parse_state: ParseState {
+                                    id_states: vec![IdState::Unknown; header.bound as usize],
+                                },
+                            })
+                        }
                     }
                     fn next_helper(&mut self, length_and_opcode: u32) -> Result<Instruction> {
                         let length = (length_and_opcode >> 16) as usize;