TreFile: save "flags" field; iffexplore: robuster parsing
This commit is contained in:
23
TreFile.cc
23
TreFile.cc
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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_;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user