gsdx: Fix GS dump readback EOF handling

An EOF only occurs after attempting to read past the end of the file.
Account for this correctly, which fixes a potential infinite loop when
reading back an xz compressed GS dump.
This commit is contained in:
Jonathan Li 2017-05-27 12:21:09 +01:00 committed by Gregory Hainaut
parent a6ed698fca
commit 742b0edaa8
3 changed files with 29 additions and 27 deletions

View File

@ -1603,11 +1603,9 @@ EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
file->Read(regs, 0x2000);
while(!file->IsEof())
uint8 type;
while(file->Read(&type, 1))
{
uint8 type;
file->Read(&type, 1);
Packet* p = new Packet();
p->type = type;

View File

@ -111,14 +111,14 @@ void GSDumpLzma::Decompress() {
}
bool GSDumpLzma::IsEof() {
return feof(m_fp) && (m_avail == 0);
return feof(m_fp) && m_avail == 0 && m_strm.avail_in == 0;
}
void GSDumpLzma::Read(void* ptr, size_t size) {
bool GSDumpLzma::Read(void* ptr, size_t size) {
size_t off = 0;
uint8_t* dst = (uint8_t*)ptr;
size_t full_size = size;
while (size) {
while (size && !IsEof()) {
if (m_avail == 0) {
Decompress();
}
@ -130,7 +130,13 @@ void GSDumpLzma::Read(void* ptr, size_t size) {
m_start += l;
off += l;
}
Repack(ptr, full_size);
if (size == 0) {
Repack(ptr, full_size);
return true;
}
return false;
}
GSDumpLzma::~GSDumpLzma() {
@ -156,17 +162,17 @@ bool GSDumpRaw::IsEof() {
return feof(m_fp);
}
void GSDumpRaw::Read(void* ptr, size_t size) {
if (size == 1) {
// I don't know why but read of size 1 is not happy
int v = fgetc(m_fp);
memcpy(ptr, &v, 1);
} else {
size_t ret = fread(ptr, 1, size, m_fp);
if (ret != size) {
fprintf(stderr, "GSDumpRaw:: Read error (%zu/%zu)\n", ret, size);
throw "BAD"; // Just exit the program
}
bool GSDumpRaw::Read(void* ptr, size_t size) {
size_t ret = fread(ptr, 1, size, m_fp);
if (ret != size && ferror(m_fp)) {
fprintf(stderr, "GSDumpRaw:: Read error (%zu/%zu)\n", ret, size);
throw "BAD"; // Just exit the program
}
Repack(ptr, size);
if (ret == size) {
Repack(ptr, size);
return true;
}
return false;
}

View File

@ -30,7 +30,7 @@ class GSDumpFile {
public:
virtual bool IsEof() = 0;
virtual void Read(void* ptr, size_t size) = 0;
virtual bool Read(void* ptr, size_t size) = 0;
GSDumpFile(char* filename, const char* repack_filename);
virtual ~GSDumpFile();
@ -54,8 +54,8 @@ class GSDumpLzma : public GSDumpFile {
GSDumpLzma(char* filename, const char* repack_filename);
virtual ~GSDumpLzma();
bool IsEof();
void Read(void* ptr, size_t size);
bool IsEof() final;
bool Read(void* ptr, size_t size) final;
};
class GSDumpRaw : public GSDumpFile {
@ -67,13 +67,11 @@ class GSDumpRaw : public GSDumpFile {
size_t m_avail;
size_t m_start;
void Decompress();
public:
GSDumpRaw(char* filename, const char* repack_filename);
virtual ~GSDumpRaw() = default;
bool IsEof();
void Read(void* ptr, size_t size);
bool IsEof() final;
bool Read(void* ptr, size_t size) final;
};