Reject SPIR-V modules with garbage ID bound.

SPIR-V spec has a limit of ~4 million, and Vulkan spec does not increase
this bound, so be a bit defensive and fail early.
This commit is contained in:
Hans-Kristian Arntzen 2020-02-14 12:57:01 +01:00
parent c53b34765d
commit 92a4294c57
2 changed files with 16 additions and 0 deletions

View File

@ -21,8 +21,10 @@
#include <algorithm>
#include <functional>
#include <iterator>
#include <limits>
#include <memory>
#include <stack>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@ -316,6 +318,13 @@ public:
void reserve(size_t count) SPIRV_CROSS_NOEXCEPT
{
if ((count > std::numeric_limits<size_t>::max() / sizeof(T)) ||
(count > std::numeric_limits<size_t>::max() / 2))
{
// Only way this should ever happen is with garbage input, terminate.
std::terminate();
}
if (count > buffer_capacity)
{
size_t target_capacity = buffer_capacity;
@ -324,6 +333,8 @@ public:
if (target_capacity < N)
target_capacity = N;
// Need to ensure there is a POT value of target capacity which is larger than count,
// otherwise this will overflow.
while (target_capacity < count)
target_capacity <<= 1u;

View File

@ -86,6 +86,11 @@ void Parser::parse()
SPIRV_CROSS_THROW("Invalid SPIRV format.");
uint32_t bound = s[3];
const uint32_t MaximumNumberOfIDs = 0x3fffff;
if (bound > MaximumNumberOfIDs)
SPIRV_CROSS_THROW("ID bound exceeds limit of 0x3fffff.\n");
ir.set_id_bounds(bound);
uint32_t offset = 5;