Avoid out of range access to spirv data.
Avoids debug assertion crashes on MSVC 2015 when trying to access elements out of range.
This commit is contained in:
Родитель
147e53aeb2
Коммит
5ac882765d
|
@ -60,7 +60,7 @@ bool Compiler::block_is_pure(const SPIRBlock &block)
|
|||
{
|
||||
for (auto &i : block.ops)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
|
||||
switch (op)
|
||||
|
@ -119,7 +119,7 @@ void Compiler::register_global_read_dependencies(const SPIRBlock &block, uint32_
|
|||
{
|
||||
for (auto &i : block.ops)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
|
||||
switch (op)
|
||||
|
@ -443,11 +443,11 @@ static string extract_string(const vector<uint32_t> &spirv, uint32_t offset)
|
|||
void Compiler::parse()
|
||||
{
|
||||
auto len = spirv.size();
|
||||
auto s = stream(0);
|
||||
|
||||
if (len < 5)
|
||||
throw CompilerError("SPIRV file too small.");
|
||||
|
||||
auto s = spirv.data();
|
||||
|
||||
// Endian-swap if we need to.
|
||||
if (s[0] == swap_endian(MagicNumber))
|
||||
transform(begin(spirv), end(spirv), begin(spirv), [](uint32_t c) { return swap_endian(c); });
|
||||
|
@ -778,7 +778,7 @@ void Compiler::unset_decoration(uint32_t id, Decoration decoration)
|
|||
|
||||
void Compiler::parse(const Instruction &i)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
uint32_t length = i.length;
|
||||
|
||||
|
@ -1651,7 +1651,7 @@ bool Compiler::traverse_all_reachable_opcodes(const SPIRBlock &block, OpcodeHand
|
|||
// inside dead blocks ...
|
||||
for (auto &i : block.ops)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
|
||||
if (!handler.handle(op, ops, i.length))
|
||||
|
|
|
@ -168,11 +168,17 @@ namespace spirv_cross
|
|||
ShaderResources get_shader_resources() const;
|
||||
|
||||
protected:
|
||||
const uint32_t* stream(uint32_t offset) const
|
||||
const uint32_t* stream(const Instruction &instr) const
|
||||
{
|
||||
if (offset > spirv.size())
|
||||
// If we're not going to use any arguments, just return nullptr.
|
||||
// We want to avoid case where we return an out of range pointer
|
||||
// that trips debug assertions on some platforms.
|
||||
if (!instr.length)
|
||||
return nullptr;
|
||||
|
||||
if (instr.offset + instr.length > spirv.size())
|
||||
throw CompilerError("Compiler::stream() out of range.");
|
||||
return &spirv[offset];
|
||||
return &spirv[instr.offset];
|
||||
}
|
||||
std::vector<uint32_t> spirv;
|
||||
|
||||
|
|
|
@ -1353,7 +1353,7 @@ void CompilerGLSL::emit_mix_op(uint32_t result_type, uint32_t id,
|
|||
|
||||
void CompilerGLSL::emit_texture_op(const Instruction &i)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
uint32_t length = i.length;
|
||||
|
||||
|
@ -2274,7 +2274,7 @@ string CompilerGLSL::build_composite_combiner(const uint32_t *elems, uint32_t le
|
|||
|
||||
void CompilerGLSL::emit_instruction(const Instruction &i)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
uint32_t length = i.length;
|
||||
|
||||
|
@ -3615,7 +3615,7 @@ void CompilerGLSL::emit_function(SPIRFunction &func, uint64_t return_flags)
|
|||
auto &b = get<SPIRBlock>(block);
|
||||
for (auto &i : b.ops)
|
||||
{
|
||||
auto ops = stream(i.offset);
|
||||
auto ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
|
||||
if (op == OpFunctionCall)
|
||||
|
|
Загрузка…
Ссылка в новой задаче