TreFile: save "flags" field; iffexplore: robuster parsing

This commit is contained in:
2015-04-19 11:15:16 +02:00
parent a5f64e9bbf
commit f46521259c
3 changed files with 40 additions and 18 deletions

View File

@@ -132,16 +132,18 @@ void TreFile::printStructure()
printf("Files by CRC:\n"); printf("Files by CRC:\n");
for(auto const& ent : table1_) { 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<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"); printf("Files by Name:\n");
for(auto const& ent : table2_) { 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<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<uint32_t>(entry.dataPtr), table3_.push_back(std::make_tuple(static_cast<uint32_t>(entry.dataPtr),
static_cast<uint32_t>(entry.length))); static_cast<uint32_t>(entry.length),
static_cast<uint8_t>(entry.unknown2)));
} }
// Read Table 2 // Read Table 2
@@ -302,12 +305,12 @@ void TreFile::construct_()
void TreFile::dumpIdx_(std::string const& name, size_t table3Idx) void TreFile::dumpIdx_(std::string const& name, size_t table3Idx)
{ {
uint32_t ofs, len; uint32_t ofs, len;
std::tie(ofs, len) = table3_[table3Idx]; std::tie(ofs, len, std::ignore) = table3_[table3Idx];
if (ofs%2 != 0) { // if (ofs%2 != 0) {
++ofs; // ++ofs;
len; // len;
} // }
std::vector<char> buf(len); std::vector<char> buf(len);

View File

@@ -30,7 +30,7 @@ private:
std::map<uint32_t, size_t> table1_; std::map<uint32_t, size_t> table1_;
std::map<std::string, size_t> table2_; std::map<std::string, size_t> table2_;
std::vector<std::tuple<uint32_t, uint32_t> > table3_; std::vector<std::tuple<uint32_t, uint32_t, uint8_t> > table3_;
FILE* file_; FILE* file_;
off_t start_; off_t start_;
size_t length_; size_t length_;

View File

@@ -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 // pos < length due to loop condition, cast of difference to unsigned is OK
if (static_cast<unsigned>(length-pos) < sizeof(ChunkHeader)) if (static_cast<unsigned>(length-pos) < sizeof(ChunkHeader))
throw FormatException{"Remaining size < header size"}; return;
//throw FormatException{"Remaining size < header size"};
ChunkHeader header; 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"); throw POSIXException(errno, "Could not read header");
} }
if (!isalnum(header.typeID[0])) {
++pos;
continue;
}
header.length = ntohl(header.length); header.length = ntohl(header.length);
for (unsigned i = 0;i < level;++i) for (unsigned i = 0;i < level;++i)
putchar('\t'); putchar('\t');
printf("Type: %.4s, Length: %u (0x%x)", header.typeID, header.length, header.length); printf("Type: %.4s, Length: %u (0x%x)", header.typeID, header.length, header.length);
if (header.length > (length-(pos+8))) if (header.length > (length-(pos+8))) {
throw FormatException{"Length in header > remaining parent size"}; 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) { if (memcmp(header.typeID, "FORM", 4) == 0) {
char subType[4]; char subType[4];
if (fread(&subType, 4, 1, iffFile) != 1) { if (fread(&subType, 4, 1, iffFile) != 1) {
putchar('\n');
throw POSIXException(errno, "Could not read form subtype"); throw POSIXException(errno, "Could not read form subtype");
} }
printf(", SubType: %.4s\n", 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 { } else {
putchar('\n'); putchar('\n');
parseBlob(iffFile, start+pos+8, header.length, header.typeID, level+1); parseBlob(iffFile, start+pos+8, header.length, header.typeID, level+1);
} }
pos += header.length+8; 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); parseChunk(iffFile.get(), 0, statBuf.st_size);
} catch (POSIXException &ex) { } catch (POSIXException &ex) {
fflush(stdout);
fprintf(stderr, "%s\n", ex.toString().c_str()); fprintf(stderr, "%s\n", ex.toString().c_str());
return 2; return 2;
} catch (FormatException &ex) { } catch (FormatException &ex) {
fflush(stdout);
fprintf(stderr, "%s\n", ex.toString().c_str()); fprintf(stderr, "%s\n", ex.toString().c_str());
return 3; return 3;
} }