diff --git a/TreFile.cc b/TreFile.cc index 55450cc..9a5e68d 100644 --- a/TreFile.cc +++ b/TreFile.cc @@ -132,16 +132,18 @@ void TreFile::printStructure() printf("Files by CRC:\n"); for(auto const& ent : table1_) { - printf("\t%.8x -> (ofs %.8x, len %.8x)\n", ent.first, + printf("\t%.8x -> (ofs %.8x, len %.8x, flags %.2hhx)\n", ent.first, std::get<0>(table3_[ent.second]), - std::get<1>(table3_[ent.second])); + std::get<1>(table3_[ent.second]), + std::get<2>(table3_[ent.second])); } printf("Files by Name:\n"); for(auto const& ent : table2_) { - printf("\t%s -> (ofs %.8x, len %.8x)\n", ent.first.c_str(), + printf("\t%s -> (ofs %.8x, len %.8x, flags %.2hhx)\n", ent.first.c_str(), std::get<0>(table3_[ent.second]), - std::get<1>(table3_[ent.second])); + std::get<1>(table3_[ent.second]), + std::get<2>(table3_[ent.second])); } } @@ -207,7 +209,8 @@ void TreFile::construct_() } table3_.push_back(std::make_tuple(static_cast(entry.dataPtr), - static_cast(entry.length))); + static_cast(entry.length), + static_cast(entry.unknown2))); } // Read Table 2 @@ -302,12 +305,12 @@ void TreFile::construct_() void TreFile::dumpIdx_(std::string const& name, size_t table3Idx) { uint32_t ofs, len; - std::tie(ofs, len) = table3_[table3Idx]; + std::tie(ofs, len, std::ignore) = table3_[table3Idx]; - if (ofs%2 != 0) { - ++ofs; - len; - } + // if (ofs%2 != 0) { + // ++ofs; + // len; + // } std::vector buf(len); diff --git a/TreFile.hh b/TreFile.hh index 80643b1..4a1ec3a 100644 --- a/TreFile.hh +++ b/TreFile.hh @@ -30,7 +30,7 @@ private: std::map table1_; std::map table2_; - std::vector > table3_; + std::vector > table3_; FILE* file_; off_t start_; size_t length_; diff --git a/iffexplore.cc b/iffexplore.cc index e20cdb8..689029f 100644 --- a/iffexplore.cc +++ b/iffexplore.cc @@ -105,7 +105,8 @@ void parseChunk(FILE* iffFile, off_t start, off_t length, unsigned level = 0) // pos < length due to loop condition, cast of difference to unsigned is OK if (static_cast(length-pos) < sizeof(ChunkHeader)) - throw FormatException{"Remaining size < header size"}; + return; + //throw FormatException{"Remaining size < header size"}; ChunkHeader header; @@ -115,29 +116,45 @@ void parseChunk(FILE* iffFile, off_t start, off_t length, unsigned level = 0) throw POSIXException(errno, "Could not read header"); } + if (!isalnum(header.typeID[0])) { + ++pos; + continue; + } + header.length = ntohl(header.length); for (unsigned i = 0;i < level;++i) putchar('\t'); printf("Type: %.4s, Length: %u (0x%x)", header.typeID, header.length, header.length); - if (header.length > (length-(pos+8))) - throw FormatException{"Length in header > remaining parent size"}; + if (header.length > (length-(pos+8))) { + if (header.length == (length-(pos+8))+1) { + --header.length; // Fix off-by-one errors + } else { + putchar('\n'); + throw FormatException{"Length in header > remaining parent size"}; + } + } if (memcmp(header.typeID, "FORM", 4) == 0) { char subType[4]; if (fread(&subType, 4, 1, iffFile) != 1) { + putchar('\n'); throw POSIXException(errno, "Could not read form subtype"); } printf(", SubType: %.4s\n", subType); - - parseChunk(iffFile, start+pos+12, header.length-4, level+1); + + try { + parseChunk(iffFile, start+pos+12, header.length-4, level+1); + } catch (FormatException &ex) { + for (unsigned i = 0;i < level;++i) + putchar('\t'); + printf("Error parsing sub-chunk: %s\n", ex.toString().c_str()); + } } else { putchar('\n'); parseBlob(iffFile, start+pos+8, header.length, header.typeID, level+1); } pos += header.length+8; - if (pos%2 != 0) - ++pos; } } @@ -163,9 +180,11 @@ int main(int argc, char *argv[]) parseChunk(iffFile.get(), 0, statBuf.st_size); } catch (POSIXException &ex) { + fflush(stdout); fprintf(stderr, "%s\n", ex.toString().c_str()); return 2; } catch (FormatException &ex) { + fflush(stdout); fprintf(stderr, "%s\n", ex.toString().c_str()); return 3; }