From 14a263d5b629ce39c1a924cc4acd91c2d6d585df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 4 Dec 2017 17:23:29 +0100 Subject: [PATCH 1/6] Reformat chunk_file. Don't usually reformat whole files, but this was too ugly to work on :P --- ext/native/file/chunk_file.cpp | 233 +++++++++++++++------------------ ext/native/file/chunk_file.h | 33 +++-- 2 files changed, 123 insertions(+), 143 deletions(-) diff --git a/ext/native/file/chunk_file.cpp b/ext/native/file/chunk_file.cpp index 0544417a33..0c3f2fb5c2 100644 --- a/ext/native/file/chunk_file.cpp +++ b/ext/native/file/chunk_file.cpp @@ -3,63 +3,67 @@ #include "file/zip_read.h" #include "file/file_util.h" -//#define CHUNKDEBUG +// #define CHUNKDEBUG -ChunkFile::ChunkFile(const char *filename, bool _read) { - data=0; - fn = filename; - numLevels=0; - read=_read; - pos=0; - didFail=false; +inline uint32_t flipID(uint32_t id) { + return ((id >> 24) & 0xFF) | ((id >> 8) & 0xFF00) | ((id << 8) & 0xFF0000) | ((id << 24) & 0xFF000000); +} - fastMode = read ? true : false; +ChunkFile::ChunkFile(const char *filename, bool readMode) { + data_ = 0; + filename_ = filename; + depth_ = 0; + readMode_ = readMode; + pos_ = 0; + didFail_ = false; + + fastMode = readMode_ ? true : false; if (fastMode) { size_t size; - data = (uint8_t *)VFSReadFile(filename, &size); - if (!data) { + data_ = (uint8_t *)VFSReadFile(filename, &size); + if (!data_) { ELOG("Chunkfile fail: %s", filename); - didFail = true; + didFail_ = true; return; } - eof = (int)size; + eof_ = (int)size; return; } file = openCFile(filename, "wb"); if (file) { - didFail = false; - eof = 0; - } else { - didFail = true; + didFail_ = false; + eof_ = 0; + } else { + didFail_ = true; } } -ChunkFile::ChunkFile(const uint8_t *read_data, int data_size) { - data = new uint8_t[data_size]; - memcpy(data, read_data, data_size); +ChunkFile::ChunkFile(const uint8_t *data, int dataSize) { + data_ = new uint8_t[dataSize]; + memcpy(data_, data, dataSize); fastMode = true; - numLevels = 0; - read = true; - pos = 0; - didFail = false; - eof = data_size; + depth_ = 0; + readMode_ = true; + pos_ = 0; + didFail_ = false; + eof_ = dataSize; } ChunkFile::~ChunkFile() { if (fastMode) { - delete[] data; + delete[] data_; } else { fclose(file); } } int ChunkFile::readInt() { - if (data && pos 30) + if (depth_ > 30) return false; id = flipID(id); - if (read) { + if (readMode_) { bool found = false; - //save information to restore after the next Ascend - stack[numLevels].parentStartLocation = pos; - stack[numLevels].parentEOF = eof; + // save information to restore after the next Ascend + stack[depth_].parentStartLocation = pos_; + stack[depth_].parentEOF = eof_; - ChunkInfo temp = stack[numLevels]; + ChunkInfo temp = stack[depth_]; int firstID = 0; - //let's search through children.. - while(pos>8, id>>16, id>>24); + ILOG("Couldn't find %c%c%c%c", id, id >> 8, id >> 16, id >> 24); #endif - stack[numLevels]=temp; - seekTo(stack[numLevels].parentStartLocation); + stack[depth_] = temp; + seekTo(stack[depth_].parentStartLocation); return false; } - //descend into it - //pos was set inside the loop above - eof = stack[numLevels].startLocation + stack[numLevels].length; - numLevels++; + // descend into it + // pos was set inside the loop above + eof_ = stack[depth_].startLocation + stack[depth_].length; + depth_++; #ifdef CHUNKDEBUG - ILOG("Descended into %c%c%c%c", id, id>>8, id>>16, id>>24); + ILOG("Descended into %c%c%c%c", id, id >> 8, id >> 16, id >> 24); #endif return true; } else { -#ifndef DEMO_VERSION //if this is missing.. heheh - //write a chunk id, and prepare for filling in length later +#ifndef DEMO_VERSION // if this is missing.. heheh + // write a chunk id, and prepare for filling in length later writeInt(id); - writeInt(0); //will be filled in by Ascend - stack[numLevels].startLocation=pos; - numLevels++; + writeInt(0); // will be filled in by Ascend + stack[depth_].startLocation = pos_; + depth_++; return true; #else return true; @@ -143,97 +146,77 @@ void ChunkFile::seekTo(int _pos) { if (!fastMode) { fseek(file, 0, SEEK_SET); } - pos = _pos; + pos_ = _pos; } -//let's ascend out +// let's ascend out void ChunkFile::ascend() { - if (read) { - //ascend, and restore information - numLevels--; - seekTo(stack[numLevels].parentStartLocation); - eof = stack[numLevels].parentEOF; + if (readMode_) { + // ascend, and restore information + depth_--; + seekTo(stack[depth_].parentStartLocation); + eof_ = stack[depth_].parentEOF; #ifdef CHUNKDEBUG - int id = stack[numLevels].ID; - ILOG("Ascended out of %c%c%c%c", id, id>>8, id>>16, id>>24); + int id = stack[depth_].ID; + ILOG("Ascended out of %c%c%c%c", id, id >> 8, id >> 16, id >> 24); #endif - } else { - numLevels--; - //now fill in the written length automatically - int posNow = pos; - seekTo(stack[numLevels].startLocation - 4); - writeInt(posNow-stack[numLevels].startLocation); + } else { + depth_--; + // now fill in the written length automatically + int posNow = pos_; + seekTo(stack[depth_].startLocation - 4); + writeInt(posNow - stack[depth_].startLocation); seekTo(posNow); } } -//read a block +// read a block void ChunkFile::readData(void *what, int count) { if (fastMode) { - memcpy(what, data + pos, count); + memcpy(what, data_ + pos_, count); } else { if (fread(what, 1, count, file) != (size_t)count) { ELOG("Failed to read complete %d bytes", count); } } - pos+=count; + pos_ += count; count &= 3; if (count) { - count=4-count; + count = 4 - count; if (!fastMode) { if (fseek(file, count, SEEK_CUR) != 0) { ELOG("Missing padding"); } } - pos+=count; + pos_ += count; } } -//write a block +// write a block void ChunkFile::writeData(const void *what, int count) { fwrite(what, 1, count, file); - pos+=count; - char temp[5]={0,0,0,0,0}; - count &= 3; - if (count) - { - count=4-count; + pos_ += count; + char temp[5] = { 0,0,0,0,0 }; + count &= 3; + if (count) { + count = 4 - count; fwrite(temp, 1, count, file); - pos+=count; + pos_ += count; } } -/* -void ChunkFile::writeWString(String str) { - wchar_t *text; - int len=str.length(); -#ifdef UNICODE -#error - text = str.getPointer(); -#else - text = new wchar_t[len+1]; - str.toUnicode(text); -#endif - writeInt(len); - writeData((char *)text, len * sizeof(wchar_t)); -#ifndef UNICODE - delete [] text; -#endif -} -*/ - // Takes utf-8 void ChunkFile::writeWString(const std::string &str) { unsigned short *text; int len = (int)str.length(); - text = new unsigned short[len+1]; + text = new unsigned short[len + 1]; for (int i = 0; i < len; i++) text[i] = str[i]; - text[len]=0; + text[len] = 0; writeInt(len); writeData((char *)text, len * sizeof(unsigned short)); - delete [] text; + delete[] text; } static void toUnicode(const std::string &str, uint16_t *t) { @@ -253,37 +236,37 @@ static std::string fromUnicode(const uint16_t *src, int len) { } std::string ChunkFile::readWString() { - int len=readInt(); - uint16_t *text = new uint16_t[len+1]; - readData((char *)text, len*sizeof(uint16_t)); + int len = readInt(); + uint16_t *text = new uint16_t[len + 1]; + readData((char *)text, len * sizeof(uint16_t)); text[len] = 0; std::string temp = fromUnicode(text, len); - delete [] text; + delete[] text; return temp; } void ChunkFile::writeString(const std::string &str) { uint16_t *text; int len = (int)str.size(); - text=new uint16_t[len+1]; + text = new uint16_t[len + 1]; toUnicode(str, text); writeInt(len); - writeData((char *)text,len*sizeof(uint16_t)); - delete [] text; + writeData((char *)text, len * sizeof(uint16_t)); + delete[] text; } std::string ChunkFile::readString() { - int len=readInt(); - uint16_t *text = new uint16_t[len+1]; - readData((char *)text,len*sizeof(uint16_t)); - text[len]=0; + int len = readInt(); + uint16_t *text = new uint16_t[len + 1]; + readData((char *)text, len * sizeof(uint16_t)); + text[len] = 0; std::string temp = fromUnicode(text, len); - delete [] text; + delete[] text; return temp; } int ChunkFile::getCurrentChunkSize() { - if (numLevels) - return stack[numLevels-1].length; + if (depth_) + return stack[depth_ - 1].length; else return 0; } diff --git a/ext/native/file/chunk_file.h b/ext/native/file/chunk_file.h index f1e9d8f3ee..ae46f2b6b9 100644 --- a/ext/native/file/chunk_file.h +++ b/ext/native/file/chunk_file.h @@ -10,18 +10,14 @@ // otherwise the scheme breaks. #include -#include +#include #include "base/basictypes.h" -inline uint32_t flipID(uint32_t id) { - return ((id>>24)&0xFF) | ((id>>8)&0xFF00) | ((id<<8)&0xFF0000) | ((id<<24)&0xFF000000); -} - class ChunkFile { public: - ChunkFile(const char *filename, bool _read); - ChunkFile(const uint8_t *read_data, int data_size); + ChunkFile(const char *filename, bool readMode); + ChunkFile(const uint8_t *data, int dataSize); ~ChunkFile(); @@ -43,12 +39,10 @@ public: void writeData(const void *data, int count); int getCurrentChunkSize(); - bool failed() const { return didFail; } - std::string filename() const { return fn; } + bool failed() const { return didFail_; } + std::string filename() const { return filename_; } private: - std::string fn; - FILE *file; struct ChunkInfo { int startLocation; int parentStartLocation; @@ -57,15 +51,18 @@ private: int length; }; ChunkInfo stack[32]; - int numLevels; + int depth_ = 0; - uint8_t *data; - int pos; - int eof; + uint8_t *data_; + int pos_ = 0; + int eof_ = 0; bool fastMode; - bool read; - bool didFail; + bool readMode_; + bool didFail_ = false; + + std::string filename_; + FILE *file = nullptr; void seekTo(int _pos); - int getPos() const {return pos;} + int getPos() const {return pos_;} }; From 1c0a0fefdba2b14c30f7e712d61ebe1a1a17f628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 4 Dec 2017 17:27:47 +0100 Subject: [PATCH 2/6] Remove write support from chunk_file, rename to RIFFReader --- UI/BackgroundAudio.cpp | 2 +- ext/native/file/chunk_file.cpp | 189 ++++++++++----------------------- ext/native/file/chunk_file.h | 17 +-- 3 files changed, 59 insertions(+), 149 deletions(-) diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 261f4af5d2..348dd9e860 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -153,7 +153,7 @@ public: } private: - ChunkFile file_; + RIFFReader file_; uint8_t *raw_data_; int raw_data_size_; int raw_offset_; diff --git a/ext/native/file/chunk_file.cpp b/ext/native/file/chunk_file.cpp index 0c3f2fb5c2..1099e2ae25 100644 --- a/ext/native/file/chunk_file.cpp +++ b/ext/native/file/chunk_file.cpp @@ -9,15 +9,14 @@ inline uint32_t flipID(uint32_t id) { return ((id >> 24) & 0xFF) | ((id >> 8) & 0xFF00) | ((id << 8) & 0xFF0000) | ((id << 24) & 0xFF000000); } -ChunkFile::ChunkFile(const char *filename, bool readMode) { +RIFFReader::RIFFReader(const char *filename) { data_ = 0; filename_ = filename; depth_ = 0; - readMode_ = readMode; pos_ = 0; didFail_ = false; - fastMode = readMode_ ? true : false; + fastMode = true; if (fastMode) { size_t size; @@ -40,18 +39,17 @@ ChunkFile::ChunkFile(const char *filename, bool readMode) { } } -ChunkFile::ChunkFile(const uint8_t *data, int dataSize) { +RIFFReader::RIFFReader(const uint8_t *data, int dataSize) { data_ = new uint8_t[dataSize]; memcpy(data_, data, dataSize); fastMode = true; depth_ = 0; - readMode_ = true; pos_ = 0; didFail_ = false; eof_ = dataSize; } -ChunkFile::~ChunkFile() { +RIFFReader::~RIFFReader() { if (fastMode) { delete[] data_; } else { @@ -59,7 +57,7 @@ ChunkFile::~ChunkFile() { } } -int ChunkFile::readInt() { +int RIFFReader::readInt() { if (data_ && pos_ < eof_) { pos_ += 4; if (fastMode) @@ -74,75 +72,57 @@ int ChunkFile::readInt() { return 0; } -void ChunkFile::writeInt(int i) { - fwrite(&i, 1, 4, file); - pos_ += 4; -} - // let's get into the business -bool ChunkFile::descend(uint32_t id) { +bool RIFFReader::descend(uint32_t id) { if (depth_ > 30) return false; id = flipID(id); - if (readMode_) { - bool found = false; + bool found = false; - // save information to restore after the next Ascend - stack[depth_].parentStartLocation = pos_; - stack[depth_].parentEOF = eof_; + // save information to restore after the next Ascend + stack[depth_].parentStartLocation = pos_; + stack[depth_].parentEOF = eof_; - ChunkInfo temp = stack[depth_]; + 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_; - - if (stack[depth_].ID == id) { - found = true; - break; - } else { - seekTo(pos_ + stack[depth_].length); // try next block - } - } - - // if we found nothing, return false so the caller can skip this - if (!found) { -#ifdef CHUNKDEBUG - ILOG("Couldn't find %c%c%c%c", id, id >> 8, id >> 16, id >> 24); -#endif - stack[depth_] = temp; - seekTo(stack[depth_].parentStartLocation); - return false; - } - - // descend into it - // pos was set inside the loop above - eof_ = stack[depth_].startLocation + stack[depth_].length; - depth_++; -#ifdef CHUNKDEBUG - ILOG("Descended into %c%c%c%c", id, id >> 8, id >> 16, id >> 24); -#endif - return true; - } else { -#ifndef DEMO_VERSION // if this is missing.. heheh - // write a chunk id, and prepare for filling in length later - writeInt(id); - writeInt(0); // will be filled in by Ascend + 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_; - depth_++; - return true; -#else - return true; -#endif + + if (stack[depth_].ID == id) { + found = true; + break; + } else { + seekTo(pos_ + stack[depth_].length); // try next block + } } + + // if we found nothing, return false so the caller can skip this + if (!found) { +#ifdef CHUNKDEBUG + ILOG("Couldn't find %c%c%c%c", id, id >> 8, id >> 16, id >> 24); +#endif + stack[depth_] = temp; + seekTo(stack[depth_].parentStartLocation); + return false; + } + + // descend into it + // pos was set inside the loop above + eof_ = stack[depth_].startLocation + stack[depth_].length; + depth_++; +#ifdef CHUNKDEBUG + ILOG("Descended into %c%c%c%c", id, id >> 8, id >> 16, id >> 24); +#endif + return true; } -void ChunkFile::seekTo(int _pos) { +void RIFFReader::seekTo(int _pos) { if (!fastMode) { fseek(file, 0, SEEK_SET); } @@ -150,28 +130,19 @@ void ChunkFile::seekTo(int _pos) { } // let's ascend out -void ChunkFile::ascend() { - if (readMode_) { - // ascend, and restore information - depth_--; - seekTo(stack[depth_].parentStartLocation); - eof_ = stack[depth_].parentEOF; +void RIFFReader::ascend() { + // ascend, and restore information + depth_--; + seekTo(stack[depth_].parentStartLocation); + eof_ = stack[depth_].parentEOF; #ifdef CHUNKDEBUG - int id = stack[depth_].ID; - ILOG("Ascended out of %c%c%c%c", id, id >> 8, id >> 16, id >> 24); + int id = stack[depth_].ID; + ILOG("Ascended out of %c%c%c%c", id, id >> 8, id >> 16, id >> 24); #endif - } else { - depth_--; - // now fill in the written length automatically - int posNow = pos_; - seekTo(stack[depth_].startLocation - 4); - writeInt(posNow - stack[depth_].startLocation); - seekTo(posNow); - } } // read a block -void ChunkFile::readData(void *what, int count) { +void RIFFReader::readData(void *what, int count) { if (fastMode) { memcpy(what, data_ + pos_, count); } else { @@ -193,39 +164,6 @@ void ChunkFile::readData(void *what, int count) { } } -// write a block -void ChunkFile::writeData(const void *what, int count) { - fwrite(what, 1, count, file); - pos_ += count; - char temp[5] = { 0,0,0,0,0 }; - count &= 3; - if (count) { - count = 4 - count; - fwrite(temp, 1, count, file); - pos_ += count; - } -} - -// Takes utf-8 -void ChunkFile::writeWString(const std::string &str) { - unsigned short *text; - int len = (int)str.length(); - text = new unsigned short[len + 1]; - for (int i = 0; i < len; i++) - text[i] = str[i]; - text[len] = 0; - writeInt(len); - writeData((char *)text, len * sizeof(unsigned short)); - delete[] text; -} - -static void toUnicode(const std::string &str, uint16_t *t) { - for (size_t i = 0; i < str.size(); i++) { - *t++ = str[i]; - } - *t++ = '\0'; -} - static std::string fromUnicode(const uint16_t *src, int len) { std::string str; str.resize(len); @@ -235,7 +173,7 @@ static std::string fromUnicode(const uint16_t *src, int len) { return str; } -std::string ChunkFile::readWString() { +std::string RIFFReader::readWString() { int len = readInt(); uint16_t *text = new uint16_t[len + 1]; readData((char *)text, len * sizeof(uint16_t)); @@ -245,26 +183,7 @@ std::string ChunkFile::readWString() { return temp; } -void ChunkFile::writeString(const std::string &str) { - uint16_t *text; - int len = (int)str.size(); - text = new uint16_t[len + 1]; - toUnicode(str, text); - writeInt(len); - writeData((char *)text, len * sizeof(uint16_t)); - delete[] text; -} - -std::string ChunkFile::readString() { - int len = readInt(); - uint16_t *text = new uint16_t[len + 1]; - readData((char *)text, len * sizeof(uint16_t)); - text[len] = 0; - std::string temp = fromUnicode(text, len); - delete[] text; - return temp; -} -int ChunkFile::getCurrentChunkSize() { +int RIFFReader::getCurrentChunkSize() { if (depth_) return stack[depth_ - 1].length; else diff --git a/ext/native/file/chunk_file.h b/ext/native/file/chunk_file.h index ae46f2b6b9..8a3cb8f0e9 100644 --- a/ext/native/file/chunk_file.h +++ b/ext/native/file/chunk_file.h @@ -14,12 +14,12 @@ #include "base/basictypes.h" -class ChunkFile { +class RIFFReader { public: - ChunkFile(const char *filename, bool readMode); - ChunkFile(const uint8_t *data, int dataSize); + RIFFReader(const char *filename); + RIFFReader(const uint8_t *data, int dataSize); - ~ChunkFile(); + ~RIFFReader(); bool descend(uint32_t id); void ascend(); @@ -30,14 +30,6 @@ public: // String readWString(); std::string readWString(); - void writeString(const std::string &str); - std::string readString(); - - void writeInt(int i); - //void writeWString(String str); - void writeWString(const std::string &str); - void writeData(const void *data, int count); - int getCurrentChunkSize(); bool failed() const { return didFail_; } std::string filename() const { return filename_; } @@ -57,7 +49,6 @@ private: int pos_ = 0; int eof_ = 0; bool fastMode; - bool readMode_; bool didFail_ = false; std::string filename_; From 210b70ff0c8ae4f5fefe68c8232a854faa0cecb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 4 Dec 2017 17:29:48 +0100 Subject: [PATCH 3/6] Kill off more unused code in RIFFReader --- ext/native/file/chunk_file.cpp | 62 ++-------------------------------- ext/native/file/chunk_file.h | 7 ---- 2 files changed, 3 insertions(+), 66 deletions(-) diff --git a/ext/native/file/chunk_file.cpp b/ext/native/file/chunk_file.cpp index 1099e2ae25..fba5c2c293 100644 --- a/ext/native/file/chunk_file.cpp +++ b/ext/native/file/chunk_file.cpp @@ -9,40 +9,9 @@ inline uint32_t flipID(uint32_t id) { return ((id >> 24) & 0xFF) | ((id >> 8) & 0xFF00) | ((id << 8) & 0xFF0000) | ((id << 24) & 0xFF000000); } -RIFFReader::RIFFReader(const char *filename) { - data_ = 0; - filename_ = filename; - depth_ = 0; - pos_ = 0; - didFail_ = false; - - fastMode = true; - - if (fastMode) { - size_t size; - data_ = (uint8_t *)VFSReadFile(filename, &size); - if (!data_) { - ELOG("Chunkfile fail: %s", filename); - didFail_ = true; - return; - } - eof_ = (int)size; - return; - } - - file = openCFile(filename, "wb"); - if (file) { - didFail_ = false; - eof_ = 0; - } else { - didFail_ = true; - } -} - RIFFReader::RIFFReader(const uint8_t *data, int dataSize) { data_ = new uint8_t[dataSize]; memcpy(data_, data, dataSize); - fastMode = true; depth_ = 0; pos_ = 0; didFail_ = false; @@ -50,24 +19,13 @@ RIFFReader::RIFFReader(const uint8_t *data, int dataSize) { } RIFFReader::~RIFFReader() { - if (fastMode) { - delete[] data_; - } else { - fclose(file); - } + delete[] data_; } int RIFFReader::readInt() { if (data_ && pos_ < eof_) { pos_ += 4; - if (fastMode) - return *(int *)(data_ + pos_ - 4); - else { - int i; - if (fread(&i, 1, 4, file) == 4) { - return i; - } - } + return *(int *)(data_ + pos_ - 4); } return 0; } @@ -123,9 +81,6 @@ bool RIFFReader::descend(uint32_t id) { } void RIFFReader::seekTo(int _pos) { - if (!fastMode) { - fseek(file, 0, SEEK_SET); - } pos_ = _pos; } @@ -143,23 +98,12 @@ void RIFFReader::ascend() { // read a block void RIFFReader::readData(void *what, int count) { - if (fastMode) { - memcpy(what, data_ + pos_, count); - } else { - if (fread(what, 1, count, file) != (size_t)count) { - ELOG("Failed to read complete %d bytes", count); - } - } + memcpy(what, data_ + pos_, count); pos_ += count; count &= 3; if (count) { count = 4 - count; - if (!fastMode) { - if (fseek(file, count, SEEK_CUR) != 0) { - ELOG("Missing padding"); - } - } pos_ += count; } } diff --git a/ext/native/file/chunk_file.h b/ext/native/file/chunk_file.h index 8a3cb8f0e9..decb0c36ab 100644 --- a/ext/native/file/chunk_file.h +++ b/ext/native/file/chunk_file.h @@ -16,9 +16,7 @@ class RIFFReader { public: - RIFFReader(const char *filename); RIFFReader(const uint8_t *data, int dataSize); - ~RIFFReader(); bool descend(uint32_t id); @@ -32,7 +30,6 @@ public: int getCurrentChunkSize(); bool failed() const { return didFail_; } - std::string filename() const { return filename_; } private: struct ChunkInfo { @@ -48,12 +45,8 @@ private: uint8_t *data_; int pos_ = 0; int eof_ = 0; - bool fastMode; bool didFail_ = false; - std::string filename_; - FILE *file = nullptr; - void seekTo(int _pos); int getPos() const {return pos_;} }; From b47251dbd4f243a5fd4501b19ce56ac2303fca45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 4 Dec 2017 17:33:42 +0100 Subject: [PATCH 4/6] Even more cleanup of RIFFReader --- UI/BackgroundAudio.cpp | 34 ++++++++++----------- ext/native/file/chunk_file.cpp | 56 ++++++---------------------------- ext/native/file/chunk_file.h | 24 +++++---------- 3 files changed, 35 insertions(+), 79 deletions(-) diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 348dd9e860..c87237c0ac 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -31,10 +31,10 @@ public: u8 at3_extradata[16]; int num_channels, sample_rate, numFrames, samplesPerSec, avgBytesPerSec, Nothing; - if (file_.descend('RIFF')) { - file_.readInt(); //get past 'WAVE' - if (file_.descend('fmt ')) { //enter the format chunk - int temp = file_.readInt(); + if (file_.Descend('RIFF')) { + file_.ReadInt(); //get past 'WAVE' + if (file_.Descend('fmt ')) { //enter the format chunk + int temp = file_.ReadInt(); int format = temp & 0xFFFF; switch (format) { case 0xFFFE: @@ -50,10 +50,10 @@ public: num_channels = temp >> 16; - samplesPerSec = file_.readInt(); - avgBytesPerSec = file_.readInt(); + samplesPerSec = file_.ReadInt(); + avgBytesPerSec = file_.ReadInt(); - temp = file_.readInt(); + temp = file_.ReadInt(); raw_bytes_per_frame_ = temp & 0xFFFF; Nothing = temp >> 16; @@ -64,41 +64,41 @@ public: if (codec == PSP_CODEC_AT3) { // The first two bytes are actually not a useful part of the extradata. // We already read 16 bytes, so make sure there's enough left. - if (file_.getCurrentChunkSize() >= 32) { - file_.readData(at3_extradata, 16); + if (file_.GetCurrentChunkSize() >= 32) { + file_.ReadData(at3_extradata, 16); } else { memset(at3_extradata, 0, sizeof(at3_extradata)); } } - file_.ascend(); + file_.Ascend(); // ILOG("got fmt data: %i", samplesPerSec); } else { ELOG("Error - no format chunk in wav"); - file_.ascend(); + file_.Ascend(); return; } - if (file_.descend('data')) { //enter the data chunk - int numBytes = file_.getCurrentChunkSize(); + if (file_.Descend('data')) { //enter the data chunk + int numBytes = file_.GetCurrentChunkSize(); numFrames = numBytes / raw_bytes_per_frame_; // numFrames raw_data_ = (uint8_t *)malloc(numBytes); raw_data_size_ = numBytes; if (/*raw_bytes_per_frame_ == 280 && */ num_channels == 1 || num_channels == 2) { - file_.readData(raw_data_, numBytes); + file_.ReadData(raw_data_, numBytes); } else { ELOG("Error - bad blockalign or channels"); free(raw_data_); raw_data_ = 0; return; } - file_.ascend(); + file_.Ascend(); } else { ELOG("Error - no data chunk in wav"); - file_.ascend(); + file_.Ascend(); return; } - file_.ascend(); + file_.Ascend(); } else { ELOG("Could not descend into RIFF file. Data size=%d", (int32_t)data.size()); return; diff --git a/ext/native/file/chunk_file.cpp b/ext/native/file/chunk_file.cpp index fba5c2c293..080d3e955b 100644 --- a/ext/native/file/chunk_file.cpp +++ b/ext/native/file/chunk_file.cpp @@ -3,8 +3,6 @@ #include "file/zip_read.h" #include "file/file_util.h" -// #define CHUNKDEBUG - inline uint32_t flipID(uint32_t id) { return ((id >> 24) & 0xFF) | ((id >> 8) & 0xFF00) | ((id << 8) & 0xFF0000) | ((id << 24) & 0xFF000000); } @@ -22,7 +20,7 @@ RIFFReader::~RIFFReader() { delete[] data_; } -int RIFFReader::readInt() { +int RIFFReader::ReadInt() { if (data_ && pos_ < eof_) { pos_ += 4; return *(int *)(data_ + pos_ - 4); @@ -31,7 +29,7 @@ int RIFFReader::readInt() { } // let's get into the business -bool RIFFReader::descend(uint32_t id) { +bool RIFFReader::Descend(uint32_t id) { if (depth_ > 30) return false; @@ -47,26 +45,23 @@ bool RIFFReader::descend(uint32_t id) { int firstID = 0; // let's search through children.. while (pos_ < eof_) { - stack[depth_].ID = readInt(); + stack[depth_].ID = ReadInt(); if (firstID == 0) firstID = stack[depth_].ID | 1; - stack[depth_].length = readInt(); + stack[depth_].length = ReadInt(); stack[depth_].startLocation = pos_; if (stack[depth_].ID == id) { found = true; break; } else { - seekTo(pos_ + stack[depth_].length); // try next block + pos_ += stack[depth_].length; // try next block } } // if we found nothing, return false so the caller can skip this if (!found) { -#ifdef CHUNKDEBUG - ILOG("Couldn't find %c%c%c%c", id, id >> 8, id >> 16, id >> 24); -#endif stack[depth_] = temp; - seekTo(stack[depth_].parentStartLocation); + pos_ = stack[depth_].parentStartLocation; return false; } @@ -74,32 +69,20 @@ bool RIFFReader::descend(uint32_t id) { // pos was set inside the loop above eof_ = stack[depth_].startLocation + stack[depth_].length; depth_++; -#ifdef CHUNKDEBUG - ILOG("Descended into %c%c%c%c", id, id >> 8, id >> 16, id >> 24); -#endif return true; } -void RIFFReader::seekTo(int _pos) { - pos_ = _pos; -} - // let's ascend out -void RIFFReader::ascend() { +void RIFFReader::Ascend() { // ascend, and restore information depth_--; - seekTo(stack[depth_].parentStartLocation); + pos_ = stack[depth_].parentStartLocation; eof_ = stack[depth_].parentEOF; -#ifdef CHUNKDEBUG - int id = stack[depth_].ID; - ILOG("Ascended out of %c%c%c%c", id, id >> 8, id >> 16, id >> 24); -#endif } // read a block -void RIFFReader::readData(void *what, int count) { +void RIFFReader::ReadData(void *what, int count) { memcpy(what, data_ + pos_, count); - pos_ += count; count &= 3; if (count) { @@ -108,26 +91,7 @@ void RIFFReader::readData(void *what, int count) { } } -static std::string fromUnicode(const uint16_t *src, int len) { - std::string str; - str.resize(len); - for (int i = 0; i < len; i++) { - str[i] = src[i] > 255 ? ' ' : src[i]; - } - return str; -} - -std::string RIFFReader::readWString() { - int len = readInt(); - uint16_t *text = new uint16_t[len + 1]; - readData((char *)text, len * sizeof(uint16_t)); - text[len] = 0; - std::string temp = fromUnicode(text, len); - delete[] text; - return temp; -} - -int RIFFReader::getCurrentChunkSize() { +int RIFFReader::GetCurrentChunkSize() { if (depth_) return stack[depth_ - 1].length; else diff --git a/ext/native/file/chunk_file.h b/ext/native/file/chunk_file.h index decb0c36ab..44a693adfc 100644 --- a/ext/native/file/chunk_file.h +++ b/ext/native/file/chunk_file.h @@ -11,24 +11,20 @@ #include #include - -#include "base/basictypes.h" +#include class RIFFReader { public: RIFFReader(const uint8_t *data, int dataSize); ~RIFFReader(); - bool descend(uint32_t id); - void ascend(); + bool Descend(uint32_t id); + void Ascend(); - int readInt(); - void readInt(int &i) {i = readInt();} - void readData(void *data, int count); - // String readWString(); - std::string readWString(); + int ReadInt(); + void ReadData(void *data, int count); - int getCurrentChunkSize(); + int GetCurrentChunkSize(); bool failed() const { return didFail_; } private: @@ -36,17 +32,13 @@ private: int startLocation; int parentStartLocation; int parentEOF; - unsigned int ID; + uint32_t ID; int length; }; ChunkInfo stack[32]; - int depth_ = 0; - uint8_t *data_; int pos_ = 0; int eof_ = 0; + int depth_ = 0; bool didFail_ = false; - - void seekTo(int _pos); - int getPos() const {return pos_;} }; From b3b57f1b4771a2e30ec18806b5c787bb5d0dd48d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 4 Dec 2017 17:41:06 +0100 Subject: [PATCH 5/6] Try to protect against bad data in RIFF files (used for menu background audio only) --- ext/native/file/chunk_file.cpp | 14 +++++++++++--- ext/native/file/chunk_file.h | 2 -- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ext/native/file/chunk_file.cpp b/ext/native/file/chunk_file.cpp index 080d3e955b..8ea6799744 100644 --- a/ext/native/file/chunk_file.cpp +++ b/ext/native/file/chunk_file.cpp @@ -3,6 +3,8 @@ #include "file/zip_read.h" #include "file/file_util.h" +#include "Common/Log.h" + inline uint32_t flipID(uint32_t id) { return ((id >> 24) & 0xFF) | ((id >> 8) & 0xFF00) | ((id << 8) & 0xFF0000) | ((id << 24) & 0xFF000000); } @@ -12,7 +14,6 @@ RIFFReader::RIFFReader(const uint8_t *data, int dataSize) { memcpy(data_, data, dataSize); depth_ = 0; pos_ = 0; - didFail_ = false; eof_ = dataSize; } @@ -21,7 +22,7 @@ RIFFReader::~RIFFReader() { } int RIFFReader::ReadInt() { - if (data_ && pos_ < eof_) { + if (data_ && pos_ < eof_ - 3) { pos_ += 4; return *(int *)(data_ + pos_ - 4); } @@ -54,7 +55,14 @@ bool RIFFReader::Descend(uint32_t id) { found = true; break; } else { - pos_ += stack[depth_].length; // try next block + if (stack[depth_].length > 0) { + pos_ += stack[depth_].length; // try next block + } else { + ERROR_LOG(SYSTEM, "Bad data in RIFF file : block length %d. Not descending.", stack[depth_].length); + 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 44a693adfc..51293527af 100644 --- a/ext/native/file/chunk_file.h +++ b/ext/native/file/chunk_file.h @@ -25,7 +25,6 @@ public: void ReadData(void *data, int count); int GetCurrentChunkSize(); - bool failed() const { return didFail_; } private: struct ChunkInfo { @@ -40,5 +39,4 @@ private: int pos_ = 0; int eof_ = 0; int depth_ = 0; - bool didFail_ = false; }; 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 6/6] 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; };