Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix savegame corruption introduced in 5abb593d #199

Merged
merged 3 commits into from Apr 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 25 additions & 2 deletions src/ldb_eventcommand.cpp
Expand Up @@ -48,7 +48,7 @@ void RawStruct<RPG::EventCommand>::WriteLcf(const RPG::EventCommand& event_comma
stream.Write(event_command.code);
stream.Write(event_command.indent);
stream.WriteInt(stream.Decode(event_command.string).size());
stream.Write(stream.Decode(event_command.string));
stream.Write(event_command.string);
int count = event_command.parameters.size();
stream.Write(count);
for (int i = 0; i < count; i++)
Expand Down Expand Up @@ -139,19 +139,42 @@ void RawStruct<std::vector<RPG::EventCommand> >::ReadLcf(
// Has no size information. Is terminated by 4 times 0x00.
unsigned long startpos = stream.Tell();
unsigned long endpos = startpos + length;

for (;;) {
uint8_t ch;
stream.Read(ch);
if (ch == 0) {
stream.Seek(3, LcfReader::FromCurrent);
break;
}

if (stream.Tell() >= endpos) {
stream.Seek(endpos, LcfReader::FromStart);
fprintf(stderr, "Event command corrupted at %d\n", stream.Tell());
for (;;) {
// Try finding the real end of the event command (4 0-bytes)
int i = 0;
for (; i < 4; ++i) {
stream.Read(ch);

if (ch != 0) {
break;
}
}

if (i == 4 || stream.Eof()) {
break;
}
}

break;
}

stream.Ungetch(ch);
RPG::EventCommand command;
RawStruct<RPG::EventCommand>::ReadLcf(command, stream, 0);
event_commands.push_back(command);
}
assert(stream.Tell() == endpos);
}

void RawStruct<std::vector<RPG::EventCommand> >::WriteLcf(const std::vector<RPG::EventCommand>& event_commands, LcfWriter& stream) {
Expand Down
17 changes: 14 additions & 3 deletions src/reader_lcf.cpp
Expand Up @@ -56,7 +56,9 @@ void LcfReader::Read(void *ptr, size_t size, size_t nmemb) {
#ifdef NDEBUG
Read0(ptr, size, nmemb);
#else
assert(Read0(ptr, size, nmemb) == nmemb);
if (Read0(ptr, size, nmemb) != nmemb) {
fprintf(stderr, "Read error at %d. The file is probably corrupted\n", Tell());
}
#endif
}

Expand Down Expand Up @@ -85,16 +87,22 @@ void LcfReader::Read<uint32_t>(uint32_t& ref) {
int LcfReader::ReadInt() {
int value = 0;
unsigned char temp = 0;

int loops = 0;
do {
value <<= 7;
if (Read0(&temp, 1, 1) == 0) {
assert(value == 0);
return 0;
}
value |= temp & 0x7F;

if (loops > 5) {
fprintf(stderr, "Invalid compressed integer at %d\n", Tell());
}
++loops;
} while (temp & 0x80);
return value;

return loops > 5 ? 0 : value;
}

template <>
Expand Down Expand Up @@ -224,6 +232,9 @@ void LcfReader::SkipDebug(const struct LcfReader::Chunk& chunk_info, const char*
if ((i+1) % 16 == 0) {
fprintf(stderr, "\n");
}
if (Eof()) {
break;
}
}
fprintf(stderr, "\n");
}
Expand Down