Commit 88f2f8e1 authored by Chen Bill's avatar Chen Bill Committed by GitHub

Replay: add bounds checking (#2583)

* update WriteInt*

* read/write with different pointer

* bool ReadData(void* data, int length)

* add ReadValue<T>
parent ec69bb11
...@@ -28,7 +28,7 @@ void Replay::BeginRecord() { ...@@ -28,7 +28,7 @@ void Replay::BeginRecord() {
if(!fp) if(!fp)
return; return;
#endif #endif
pdata = replay_data; pwrite = replay_data;
replay_size = 0; replay_size = 0;
comp_size = 0; comp_size = 0;
is_replaying = false; is_replaying = false;
...@@ -47,10 +47,10 @@ void Replay::WriteHeader(ReplayHeader& header) { ...@@ -47,10 +47,10 @@ void Replay::WriteHeader(ReplayHeader& header) {
void Replay::WriteData(const void* data, int length, bool flush) { void Replay::WriteData(const void* data, int length, bool flush) {
if(!is_recording) if(!is_recording)
return; return;
if (length < 0 || (pdata - replay_data) + length > MAX_REPLAY_SIZE) if (length < 0 || (int)(pwrite - replay_data) + length > MAX_REPLAY_SIZE)
return; return;
std::memcpy(pdata, data, length); std::memcpy(pwrite, data, length);
pdata += length; pwrite += length;
#ifdef _WIN32 #ifdef _WIN32
DWORD size; DWORD size;
WriteFile(recording_fp, data, length, &size, NULL); WriteFile(recording_fp, data, length, &size, NULL);
...@@ -61,49 +61,13 @@ void Replay::WriteData(const void* data, int length, bool flush) { ...@@ -61,49 +61,13 @@ void Replay::WriteData(const void* data, int length, bool flush) {
#endif #endif
} }
void Replay::WriteInt32(int data, bool flush) { void Replay::WriteInt32(int data, bool flush) {
if(!is_recording) WriteData(&data, sizeof data, flush);
return;
if ((pdata - replay_data) + 4 > MAX_REPLAY_SIZE)
return;
BufferIO::WriteInt32(pdata, data);
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &data, sizeof(int), &size, NULL);
#else
fwrite(&data, sizeof(int), 1, fp);
if(flush)
fflush(fp);
#endif
} }
void Replay::WriteInt16(short data, bool flush) { void Replay::WriteInt16(short data, bool flush) {
if(!is_recording) WriteData(&data, sizeof data, flush);
return;
if ((pdata - replay_data) + 2 > MAX_REPLAY_SIZE)
return;
BufferIO::WriteInt16(pdata, data);
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &data, sizeof(short), &size, NULL);
#else
fwrite(&data, sizeof(short), 1, fp);
if(flush)
fflush(fp);
#endif
} }
void Replay::WriteInt8(char data, bool flush) { void Replay::WriteInt8(char data, bool flush) {
if(!is_recording) WriteData(&data, sizeof data, flush);
return;
if ((pdata - replay_data) + 1 > MAX_REPLAY_SIZE)
return;
BufferIO::WriteInt8(pdata, data);
#ifdef _WIN32
DWORD size;
WriteFile(recording_fp, &data, sizeof(char), &size, NULL);
#else
fwrite(&data, sizeof(char), 1, fp);
if(flush)
fflush(fp);
#endif
} }
void Replay::Flush() { void Replay::Flush() {
if(!is_recording) if(!is_recording)
...@@ -121,10 +85,7 @@ void Replay::EndRecord() { ...@@ -121,10 +85,7 @@ void Replay::EndRecord() {
#else #else
fclose(fp); fclose(fp);
#endif #endif
if(pdata - replay_data > 0 && pdata - replay_data <= MAX_REPLAY_SIZE) replay_size = pwrite - replay_data;
replay_size = pdata - replay_data;
else
replay_size = 0;
pheader.datasize = replay_size; pheader.datasize = replay_size;
pheader.flag |= REPLAY_COMPRESSED; pheader.flag |= REPLAY_COMPRESSED;
size_t propsize = 5; size_t propsize = 5;
...@@ -253,45 +214,53 @@ bool Replay::RenameReplay(const wchar_t* oldname, const wchar_t* newname) { ...@@ -253,45 +214,53 @@ bool Replay::RenameReplay(const wchar_t* oldname, const wchar_t* newname) {
#endif #endif
} }
bool Replay::ReadNextResponse(unsigned char resp[]) { bool Replay::ReadNextResponse(unsigned char resp[]) {
if(pdata - replay_data >= (int)replay_size) unsigned char len{};
if (!ReadData(&len, sizeof len))
return false;
if (len > SIZE_RETURN_VALUE) {
is_replaying = false;
return false; return false;
int len = *pdata++; }
if(len > SIZE_RETURN_VALUE) if (!ReadData(resp, len))
return false; return false;
std::memcpy(resp, pdata, len);
pdata += len;
return true; return true;
} }
void Replay::ReadName(wchar_t* data) { void Replay::ReadName(wchar_t* data) {
if(!is_replaying) uint16_t buffer[20]{};
if (!ReadData(buffer, sizeof buffer)) {
data[0] = 0;
return; return;
unsigned short buffer[20]; }
ReadData(buffer, 40);
BufferIO::CopyWStr(buffer, data, 20); BufferIO::CopyWStr(buffer, data, 20);
} }
void Replay::ReadData(void* data, int length) { bool Replay::ReadData(void* data, int length) {
if(!is_replaying) if(!is_replaying)
return; return false;
if (length < 0)
return false;
if ((int)(pdata - replay_data) + length > (int)replay_size) {
is_replaying = false;
return false;
}
std::memcpy(data, pdata, length); std::memcpy(data, pdata, length);
pdata += length; pdata += length;
return true;
} }
int Replay::ReadInt32() { template<typename T>
if(!is_replaying) T Replay::ReadValue() {
T ret{};
if (!ReadData(&ret, sizeof ret))
return -1; return -1;
int ret = BufferIO::ReadInt32(pdata);
return ret; return ret;
} }
int Replay::ReadInt32() {
return ReadValue<int32_t>();
}
short Replay::ReadInt16() { short Replay::ReadInt16() {
if(!is_replaying) return ReadValue<int16_t>();
return -1;
short ret = BufferIO::ReadInt16(pdata);
return ret;
} }
char Replay::ReadInt8() { char Replay::ReadInt8() {
if(!is_replaying) return ReadValue<char>();
return -1;
char ret= BufferIO::ReadInt8(pdata);
return ret;
} }
void Replay::Rewind() { void Replay::Rewind() {
pdata = replay_data; pdata = replay_data;
......
...@@ -50,7 +50,9 @@ public: ...@@ -50,7 +50,9 @@ public:
bool ReadNextResponse(unsigned char resp[]); bool ReadNextResponse(unsigned char resp[]);
void ReadName(wchar_t* data); void ReadName(wchar_t* data);
//void ReadHeader(ReplayHeader& header); //void ReadHeader(ReplayHeader& header);
void ReadData(void* data, int length); bool ReadData(void* data, int length);
template<typename T>
T ReadValue();
int ReadInt32(); int ReadInt32();
short ReadInt16(); short ReadInt16();
char ReadInt8(); char ReadInt8();
...@@ -62,13 +64,14 @@ public: ...@@ -62,13 +64,14 @@ public:
#endif #endif
ReplayHeader pheader; ReplayHeader pheader;
unsigned char* replay_data;
unsigned char* comp_data; unsigned char* comp_data;
size_t replay_size{};
size_t comp_size{}; size_t comp_size{};
private: private:
unsigned char* pdata{ nullptr }; unsigned char* replay_data;
size_t replay_size{};
unsigned char* pwrite{};
unsigned char* pdata{};
bool is_recording{}; bool is_recording{};
bool is_replaying{}; bool is_replaying{};
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment