summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Helfferich <[email protected]>2016-04-30 14:56:07 -0500
committerJulian Helfferich <[email protected]>2016-04-30 15:01:28 -0500
commit12860515871f2c4e54a55bc9de20ed55a7671507 (patch)
treeaa6e9f96eec014ea0418da635b3307c3cdb120cf
parent0a4622ce30ce2172b6cce75cc5404b1996575f20 (diff)
Fix Coverity #76255: Calling risky function
When loading a plain text replay file, fscanf() was used. The use of this function is discouraged as it can lead to buffer overflows if the string read is larger than the reserved buffer. Now, the C-style functions are replaced with their C++ equivalents. This means the data is read from an ifstream and stored to a string via an istringstream.
-rw-r--r--KBlocksDefine.cpp1
-rw-r--r--KBlocksDefine.h1
-rw-r--r--KBlocksGameReplayer.cpp95
-rw-r--r--KBlocksGameReplayer.h6
-rw-r--r--KBlocksRepWin.cpp2
5 files changed, 67 insertions, 38 deletions
diff --git a/KBlocksDefine.cpp b/KBlocksDefine.cpp
index 06a31f1..1bfcbed 100644
--- a/KBlocksDefine.cpp
+++ b/KBlocksDefine.cpp
@@ -11,6 +11,7 @@
Q_LOGGING_CATEGORY(KBGeneral, "KBlocks.General")
Q_LOGGING_CATEGORY(KBGraphics, "KBlocks.Graphics")
+Q_LOGGING_CATEGORY(KBReplay, "KBlocks.Replay")
Q_LOGGING_CATEGORY(KBSound, "KBlocks.Sound")
const char *KBlocksRecordText[RecordDataType_Max_Count] = {
diff --git a/KBlocksDefine.h b/KBlocksDefine.h
index f204cde..6c70bd2 100644
--- a/KBlocksDefine.h
+++ b/KBlocksDefine.h
@@ -14,6 +14,7 @@
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(KBGeneral)
Q_DECLARE_LOGGING_CATEGORY(KBGraphics)
+Q_DECLARE_LOGGING_CATEGORY(KBReplay)
Q_DECLARE_LOGGING_CATEGORY(KBSound)
#define PREPARE_AREA_WIDTH 5
diff --git a/KBlocksGameReplayer.cpp b/KBlocksGameReplayer.cpp
index bee82b1..6cb51fd 100644
--- a/KBlocksGameReplayer.cpp
+++ b/KBlocksGameReplayer.cpp
@@ -9,27 +9,50 @@
***************************************************************************/
#include "KBlocksGameReplayer.h"
+#include <sstream>
+#include <string>
+
+#include "KBlocksDefine.h"
+
KBlocksGameReplayer::KBlocksGameReplayer(const char *fileName, bool isBinaryMode)
{
+ // Map data types to strings for reading text file
for (int i = 0; i < RecordDataType_Max_Count; ++i) {
mRTMap[ KBlocksRecordText[i] ] = i;
}
mRTMap[string("MaxCount")] = -1;
- FILE *pFile = fopen(fileName, "r");
+ // Set default variables in case loading the file fails
+ mGameCount = 0;
+ mGameSeed = 0;
+ mSameSeed = false;
+ mStepLength = 1;
- if (!pFile) {
- mGameCount = 0;
- mGameSeed = 0;
- mSameSeed = false;
- mStepLength = 1;
+ // Open replay file
+ std::ifstream replayFile;
+ if (isBinaryMode) {
+ replayFile.open(fileName, std::ios::binary);
+ } else {
+ replayFile.open(fileName);
+ }
+
+ // Check that replay file was opened successfully
+ if (!replayFile.is_open()) {
+ qCWarning(KBReplay) << "Unable to open file " << fileName;
return;
}
if (isBinaryMode) {
- loadBinary(pFile);
+ loadBinary(replayFile);
} else {
- loadText(pFile);
+ loadText(replayFile);
+ }
+
+ // Check that more than two Replay steps have been loaded
+ // The two first steps set the required variables.
+ if (mReplayList.size() < 2) {
+ qCWarning(KBReplay) << "Problem loading replay file" << fileName;
+ return;
}
mGameCount = mReplayList.front().value;
@@ -38,9 +61,7 @@ KBlocksGameReplayer::KBlocksGameReplayer(const char *fileName, bool isBinaryMode
mSameSeed = (mReplayList.front().index == 1);
mReplayList.pop_front();
- mStepLength = 1;
-
- fclose(pFile);
+ replayFile.close();
}
KBlocksGameReplayer::~KBlocksGameReplayer()
@@ -96,48 +117,54 @@ bool KBlocksGameReplayer::getNextRecords(vector<KBlocksReplayData> *data)
return true;
}
-void KBlocksGameReplayer::loadText(FILE *pFile)
+void KBlocksGameReplayer::loadText(std::ifstream &replayFile)
{
- int count = 0;
- char tmpString[256];
+ std::string line;
+ std::istringstream inStream;
+ std::string tmpString;
KBlocksReplayData tmpData;
mReplayList.clear();
- while (1) {
- count = fscanf(pFile, "%d %s %d %d", &(tmpData.time), tmpString, &(tmpData.index), &(tmpData.value));
- tmpData.type = mRTMap[string(tmpString)];
- if ((tmpData.type == -1) || (count != 4)) {
+ do {
+ std::getline(replayFile, line);
+ inStream.str(line);
+ inStream >> tmpData.time >> tmpString >> tmpData.index >> tmpData.value;
+ tmpData.type = mRTMap[tmpString];
+ if ((tmpData.type == -1) || inStream.fail()) {
break;
}
mReplayList.push_back(tmpData);
- }
+ inStream.clear();
+ } while (!replayFile.eof());
}
-void KBlocksGameReplayer::loadBinary(FILE *pFile)
+void KBlocksGameReplayer::loadBinary(std::ifstream &replayFile)
{
KBlocksReplayData tmpData;
mReplayList.clear();
- tmpData.time = fgetc(pFile);
- tmpData.type = fgetc(pFile);
- tmpData.index = fgetc(pFile);
- tmpData.value = fgetc(pFile);
- while (tmpData.time != EOF) {
+
+ tmpData.time = replayFile.get();
+ tmpData.type = replayFile.get();
+ tmpData.index = replayFile.get();
+ tmpData.value = replayFile.get();
+
+ do {
if (tmpData.type == RecordDataType_Skipped) {
int tmpTime = tmpData.time;
while (tmpData.type == RecordDataType_Skipped) {
- tmpData.time = fgetc(pFile);
- tmpData.type = fgetc(pFile);
- tmpData.index = fgetc(pFile);
- tmpData.value = fgetc(pFile);
+ tmpData.time = replayFile.get();
+ tmpData.type = replayFile.get();
+ tmpData.index = replayFile.get();
+ tmpData.value = replayFile.get();
tmpTime += tmpData.time;
}
tmpData.time = tmpTime;
}
mReplayList.push_back(tmpData);
- tmpData.time = fgetc(pFile);
- tmpData.type = fgetc(pFile);
- tmpData.index = fgetc(pFile);
- tmpData.value = fgetc(pFile);
- }
+ tmpData.time = replayFile.get();
+ tmpData.type = replayFile.get();
+ tmpData.index = replayFile.get();
+ tmpData.value = replayFile.get();
+ } while (!replayFile.eof());
}
diff --git a/KBlocksGameReplayer.h b/KBlocksGameReplayer.h
index 2782477..fc83e12 100644
--- a/KBlocksGameReplayer.h
+++ b/KBlocksGameReplayer.h
@@ -12,7 +12,7 @@
#include "KBlocksDefine.h"
-#include <stdio.h>
+#include <fstream>
#include <string>
#include <vector>
#include <list>
@@ -46,8 +46,8 @@ public:
bool getNextRecords(vector<KBlocksReplayData> *data);
private:
- void loadText(FILE *pFile);
- void loadBinary(FILE *pFile);
+ void loadText(std::ifstream &pFile);
+ void loadBinary(std::ifstream &pFile);
private:
int mGameCount;
diff --git a/KBlocksRepWin.cpp b/KBlocksRepWin.cpp
index 5a7f17f..f4da381 100644
--- a/KBlocksRepWin.cpp
+++ b/KBlocksRepWin.cpp
@@ -160,7 +160,7 @@ void KBlocksRepWin::replayOneStep()
{
int tmpPieceChanged = 0;
if (!mpGameLogic->playRecordOneStep(&tmpPieceChanged)) {
- printf("Finished Replay!\n");
+ qCDebug(KBReplay) << "Finished Replay!";
mUpdateTimer.stop();
}
if (tmpPieceChanged != 0) {