mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
a6ed698fca
commit
742b0edaa8
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue