Validate SPIRV Version number when parsing binary header (#3834)

Fixes #3831
diff --git a/source/binary.cpp b/source/binary.cpp
index f16bf52..75a997d 100644
--- a/source/binary.cpp
+++ b/source/binary.cpp
@@ -45,6 +45,14 @@
   // TODO: Validation checking?
   pHeader->magic = spvFixWord(binary->code[SPV_INDEX_MAGIC_NUMBER], endian);
   pHeader->version = spvFixWord(binary->code[SPV_INDEX_VERSION_NUMBER], endian);
+  // Per 2.3.1 version's high and low bytes are 0
+  if ((pHeader->version & 0x000000ff) || pHeader->version & 0xff000000)
+    return SPV_ERROR_INVALID_BINARY;
+  // Minimum version was 1.0 and max version is defined by SPV_VERSION.
+  if (pHeader->version < SPV_SPIRV_VERSION_WORD(1, 0) ||
+      pHeader->version > SPV_VERSION)
+    return SPV_ERROR_INVALID_BINARY;
+
   pHeader->generator =
       spvFixWord(binary->code[SPV_INDEX_GENERATOR_NUMBER], endian);
   pHeader->bound = spvFixWord(binary->code[SPV_INDEX_BOUND], endian);
diff --git a/test/binary_header_get_test.cpp b/test/binary_header_get_test.cpp
index f8f6bdb..3ce0b63 100644
--- a/test/binary_header_get_test.cpp
+++ b/test/binary_header_get_test.cpp
@@ -81,5 +81,37 @@
   }
 }
 
+TEST_F(BinaryHeaderGet, VersionNonZeroHighByte) {
+  spv_header_t header;
+  code[1] = 0xFF010300;
+  spv_const_binary_t const_bin = get_const_binary();
+  ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
+            spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, &header));
+}
+
+TEST_F(BinaryHeaderGet, VersionNonZeroLowByte) {
+  spv_header_t header;
+  code[1] = 0x000103F0;
+  spv_const_binary_t const_bin = get_const_binary();
+  ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
+            spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, &header));
+}
+
+TEST_F(BinaryHeaderGet, VersionTooLow) {
+  spv_header_t header;
+  code[1] = 0x00000300;
+  spv_const_binary_t const_bin = get_const_binary();
+  ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
+            spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, &header));
+}
+
+TEST_F(BinaryHeaderGet, VersionTooHigh) {
+  spv_header_t header;
+  code[1] = 0x000F0300;
+  spv_const_binary_t const_bin = get_const_binary();
+  ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
+            spvBinaryHeaderGet(&const_bin, SPV_ENDIANNESS_LITTLE, &header));
+}
+
 }  // namespace
 }  // namespace spvtools
diff --git a/test/link/binary_version_test.cpp b/test/link/binary_version_test.cpp
index 0ceeeba..80aab0f 100644
--- a/test/link/binary_version_test.cpp
+++ b/test/link/binary_version_test.cpp
@@ -27,21 +27,21 @@
   spvtest::Binaries binaries = {
       {
           SpvMagicNumber,
-          0x00000300u,
+          0x00010300u,
           SPV_GENERATOR_CODEPLAY,
           1u,  // NOTE: Bound
           0u   // NOTE: Schema; reserved
       },
       {
           SpvMagicNumber,
-          0x00000600u,
+          0x00010500u,
           SPV_GENERATOR_CODEPLAY,
           1u,  // NOTE: Bound
           0u   // NOTE: Schema; reserved
       },
       {
           SpvMagicNumber,
-          0x00000100u,
+          0x00010100u,
           SPV_GENERATOR_CODEPLAY,
           1u,  // NOTE: Bound
           0u   // NOTE: Schema; reserved
@@ -53,7 +53,7 @@
   ASSERT_EQ(SPV_SUCCESS, Link(binaries, &linked_binary));
   EXPECT_THAT(GetErrorMessage(), std::string());
 
-  EXPECT_EQ(0x00000600u, linked_binary[1]);
+  EXPECT_EQ(0x00010500u, linked_binary[1]);
 }
 
 }  // namespace