From c4e8c509d607ff2e76b7cf3760f630de7a014c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 4 Dec 2017 18:01:51 +0100 Subject: [PATCH] RIFF: Add check for truncated files, cleanup a little more. --- ext/native/file/chunk_file.cpp | 34 +++++++++++++++++++--------------- ext/native/file/chunk_file.h | 3 ++- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/ext/native/file/chunk_file.cpp b/ext/native/file/chunk_file.cpp index 8ea6799744..4cd4e5157c 100644 --- a/ext/native/file/chunk_file.cpp +++ b/ext/native/file/chunk_file.cpp @@ -15,6 +15,7 @@ RIFFReader::RIFFReader(const uint8_t *data, int dataSize) { depth_ = 0; pos_ = 0; eof_ = dataSize; + fileSize_ = dataSize; } RIFFReader::~RIFFReader() { @@ -30,36 +31,40 @@ int RIFFReader::ReadInt() { } // let's get into the business -bool RIFFReader::Descend(uint32_t id) { +bool RIFFReader::Descend(uint32_t intoId) { if (depth_ > 30) return false; - id = flipID(id); + intoId = flipID(intoId); bool found = false; // save information to restore after the next Ascend stack[depth_].parentStartLocation = pos_; stack[depth_].parentEOF = eof_; - ChunkInfo temp = stack[depth_]; - - int firstID = 0; // let's search through children.. while (pos_ < eof_) { - stack[depth_].ID = ReadInt(); - if (firstID == 0) firstID = stack[depth_].ID | 1; - stack[depth_].length = ReadInt(); - stack[depth_].startLocation = pos_; + int id = ReadInt(); + int length = ReadInt(); + int startLocation = pos_; - if (stack[depth_].ID == id) { + if (pos_ + length > fileSize_) { + ERROR_LOG(SYSTEM, "Block extends outside of RIFF file - failing descend"); + pos_ = stack[depth_].parentStartLocation; + return false; + } + + if (id == intoId) { + stack[depth_].ID = intoId; + stack[depth_].length = length; + stack[depth_].startLocation = startLocation; found = true; break; } else { - if (stack[depth_].length > 0) { - pos_ += stack[depth_].length; // try next block + if (length > 0) { + pos_ += length; // try next block } else { - ERROR_LOG(SYSTEM, "Bad data in RIFF file : block length %d. Not descending.", stack[depth_].length); - stack[depth_] = temp; + ERROR_LOG(SYSTEM, "Bad data in RIFF file : block length %d. Not descending.", length); pos_ = stack[depth_].parentStartLocation; return false; } @@ -68,7 +73,6 @@ bool RIFFReader::Descend(uint32_t id) { // if we found nothing, return false so the caller can skip this if (!found) { - stack[depth_] = temp; pos_ = stack[depth_].parentStartLocation; return false; } diff --git a/ext/native/file/chunk_file.h b/ext/native/file/chunk_file.h index 51293527af..18d8a80e8b 100644 --- a/ext/native/file/chunk_file.h +++ b/ext/native/file/chunk_file.h @@ -37,6 +37,7 @@ private: ChunkInfo stack[32]; uint8_t *data_; int pos_ = 0; - int eof_ = 0; + int eof_ = 0; // really end of current block int depth_ = 0; + int fileSize_ = 0; };