mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-31 03:41:01 +00:00
Handle unknown pNext structs more gracefully in serialisation
* It's illegal for an application to pass an unknown pNext struct since they must correspond to enabled extensions and we disallow all unsupported extensions. * Rather than crashing or corrupting the serialisation though we strip and don't serialise the extension struct. This may or may not succeed but the application is already in undefined territory. * When we encounter an unsupported extension on replay this cannot be handled since we don't know how to skip its serialisation. This becomes a fatal error.
This commit is contained in:
@@ -1244,12 +1244,15 @@ static void SerialiseNext(SerialiserType &ser, VkStructureType &sType, const voi
|
||||
// thing user-facing.
|
||||
ser.Named("pNextType"_lit).Hidden();
|
||||
|
||||
// if we encounter an unsupported struct on read we *cannot* continue since we don't know the
|
||||
// members that got serialised after it
|
||||
#define PNEXT_UNSUPPORTED(StructType) \
|
||||
case StructType: \
|
||||
{ \
|
||||
RDCERR("No support for " #StructType " is available in this build"); \
|
||||
pNext = NULL; \
|
||||
break; \
|
||||
ser.SetErrored(); \
|
||||
return; \
|
||||
}
|
||||
|
||||
// if we come across a struct we should process, then serialise a pointer to it.
|
||||
@@ -1287,12 +1290,15 @@ static void SerialiseNext(SerialiserType &ser, VkStructureType &sType, const voi
|
||||
}
|
||||
else // ser.IsWriting()
|
||||
{
|
||||
// if we hit an unsupported struct, error and then just skip it entirely from the chain and move
|
||||
// onto the next one in the list
|
||||
#undef PNEXT_UNSUPPORTED
|
||||
#define PNEXT_UNSUPPORTED(StructType) \
|
||||
case StructType: \
|
||||
{ \
|
||||
RDCERR("No support for " #StructType " is available in this build"); \
|
||||
return; \
|
||||
handled = true; \
|
||||
break; \
|
||||
}
|
||||
|
||||
// if we come across a struct we should process, then serialise a pointer to its type (to tell the
|
||||
@@ -1326,7 +1332,8 @@ static void SerialiseNext(SerialiserType &ser, VkStructureType &sType, const voi
|
||||
case VK_STRUCTURE_TYPE_MAX_ENUM: break;
|
||||
}
|
||||
|
||||
RDCERR("Invalid pNext structure sType: %u", next->sType);
|
||||
if(!handled)
|
||||
RDCERR("Invalid pNext structure sType: %u", next->sType);
|
||||
|
||||
// walk to the next item if we didn't serialise the current one
|
||||
next = (VkBaseInStructure *)next->pNext;
|
||||
@@ -1352,6 +1359,14 @@ static inline void DeserialiseNext(const void *pNext)
|
||||
if(pNext == NULL)
|
||||
return;
|
||||
|
||||
#undef PNEXT_UNSUPPORTED
|
||||
#define PNEXT_UNSUPPORTED(StructType) \
|
||||
case StructType: \
|
||||
{ \
|
||||
RDCERR("No support for " #StructType " is available in this build"); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#undef PNEXT_STRUCT
|
||||
#define PNEXT_STRUCT(StructType, StructName) \
|
||||
case StructType: \
|
||||
|
||||
@@ -115,6 +115,7 @@ public:
|
||||
Serialiser(const Serialiser &other) = delete;
|
||||
|
||||
bool IsErrored() { return IsReading() ? m_Read->IsErrored() : m_Write->IsErrored(); }
|
||||
void SetErrored() { IsReading() ? m_Read->SetErrored() : m_Write->SetErrored(); }
|
||||
bool IsDummy() { return m_Dummy; }
|
||||
StreamWriter *GetWriter() { return m_Write; }
|
||||
StreamReader *GetReader() { return m_Read; }
|
||||
|
||||
@@ -92,6 +92,7 @@ public:
|
||||
~StreamReader();
|
||||
|
||||
bool IsErrored() { return m_HasError; }
|
||||
void SetErrored() { m_HasError = true; }
|
||||
void SetOffset(uint64_t offs);
|
||||
|
||||
inline uint64_t GetOffset() { return m_BufferHead - m_BufferBase + m_ReadOffset; }
|
||||
@@ -129,7 +130,7 @@ public:
|
||||
if(numBytes == 0 || m_Dummy)
|
||||
return true;
|
||||
|
||||
if(!m_BufferBase)
|
||||
if(!m_BufferBase || m_HasError)
|
||||
{
|
||||
// read 0s if we're in an error state
|
||||
if(data)
|
||||
@@ -296,6 +297,7 @@ public:
|
||||
StreamWriter(Compressor *compressor, Ownership own);
|
||||
|
||||
bool IsErrored() { return m_HasError; }
|
||||
void SetErrored() { m_HasError = true; }
|
||||
static const int DefaultScratchSize = 32 * 1024;
|
||||
|
||||
~StreamWriter();
|
||||
|
||||
Reference in New Issue
Block a user