Fix RagePhoto runtime crashes, const improvements
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Syping 2021-03-22 05:40:30 +01:00
parent 4e004b1d68
commit a4bc9a3b75
2 changed files with 88 additions and 37 deletions

View File

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2020 Syping * Copyright (C) 2016-2021 Syping
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -49,7 +49,7 @@ void ProfileLoader::run()
SavegameFiles.removeDuplicates(); SavegameFiles.removeDuplicates();
SnapmaticPics.removeDuplicates(); SnapmaticPics.removeDuplicates();
for (const QString &BackupFile : BackupFiles) { for (const QString &BackupFile : qAsConst(BackupFiles)) {
SavegameFiles.removeAll(BackupFile); SavegameFiles.removeAll(BackupFile);
SnapmaticPics.removeAll(BackupFile); SnapmaticPics.removeAll(BackupFile);
} }
@ -58,7 +58,7 @@ void ProfileLoader::run()
// Loading pictures and savegames // Loading pictures and savegames
emit loadingProgress(curFile, maximumV); emit loadingProgress(curFile, maximumV);
for (const QString &SavegameFile : SavegameFiles) { for (const QString &SavegameFile : qAsConst(SavegameFiles)) {
emit loadingProgress(curFile, maximumV); emit loadingProgress(curFile, maximumV);
const QString sgdPath = profileFolder % "/" % SavegameFile; const QString sgdPath = profileFolder % "/" % SavegameFile;
SavegameData *savegame = new SavegameData(sgdPath); SavegameData *savegame = new SavegameData(sgdPath);
@ -67,10 +67,11 @@ void ProfileLoader::run()
} }
curFile++; curFile++;
} }
for (const QString &SnapmaticPic : SnapmaticPics) { for (const QString &SnapmaticPic : qAsConst(SnapmaticPics)) {
emit loadingProgress(curFile, maximumV); emit loadingProgress(curFile, maximumV);
const QString picturePath = profileFolder % "/" % SnapmaticPic; const QString picturePath = profileFolder % "/" % SnapmaticPic;
SnapmaticPicture *picture = new SnapmaticPicture(picturePath); SnapmaticPicture *picture = new SnapmaticPicture(picturePath);
QTextStream(stdout) << "Current: " << picturePath << Qt::endl;
if (picture->readingPicture(true)) { if (picture->readingPicture(true)) {
if (picture->isFormatSwitched()) { if (picture->isFormatSwitched()) {
picture->setSnapmaticFormat(SnapmaticFormat::PGTA_Format); picture->setSnapmaticFormat(SnapmaticFormat::PGTA_Format);
@ -89,7 +90,7 @@ void ProfileLoader::run()
// adding found crews // adding found crews
crewDB->setAddingCrews(true); crewDB->setAddingCrews(true);
for (int crewID : crewList) { for (int crewID : qAsConst(crewList)) {
crewDB->addCrew(crewID); crewDB->addCrew(crewID);
} }
crewDB->setAddingCrews(false); crewDB->setAddingCrews(false);

View File

@ -1,6 +1,6 @@
/***************************************************************************** /*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer * gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2020 Syping * Copyright (C) 2020-2021 Syping
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -90,15 +90,20 @@ bool RagePhoto::load()
quint32 format = charToUInt32LE(uInt32Buffer); quint32 format = charToUInt32LE(uInt32Buffer);
if (format == static_cast<quint32>(PhotoFormat::GTA5)) { if (format == static_cast<quint32>(PhotoFormat::GTA5)) {
char photoHeader[256]; char *photoHeader = static_cast<char*>(malloc(256));
size = dataBuffer.read(photoHeader, 256); if (!photoHeader)
if (size != 256)
return false; return false;
size = dataBuffer.read(photoHeader, 256);
if (size != 256) {
free(photoHeader);
return false;
}
for (const QChar &photoChar : utf16LEToString(photoHeader, 256)) { for (const QChar &photoChar : utf16LEToString(photoHeader, 256)) {
if (photoChar.isNull()) if (photoChar.isNull())
break; break;
p_photoString += photoChar; p_photoString += photoChar;
} }
free(photoHeader);
size = dataBuffer.read(uInt32Buffer, 4); size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4) if (size != 4)
@ -142,11 +147,16 @@ bool RagePhoto::load()
return false; return false;
quint32 t_photoSize = charToUInt32LE(uInt32Buffer); quint32 t_photoSize = charToUInt32LE(uInt32Buffer);
char photoData[t_photoSize]; char *photoData = static_cast<char*>(malloc(t_photoSize));
size = dataBuffer.read(photoData, t_photoSize); if (!photoData)
if (size != t_photoSize)
return false; return false;
size = dataBuffer.read(photoData, t_photoSize);
if (size != t_photoSize) {
free(photoData);
return false;
}
p_photoData = QByteArray(photoData, t_photoSize); p_photoData = QByteArray(photoData, t_photoSize);
free(photoData);
dataBuffer.seek(p_jsonOffset + 264); dataBuffer.seek(p_jsonOffset + 264);
size = dataBuffer.read(markerBuffer, 4); size = dataBuffer.read(markerBuffer, 4);
@ -160,15 +170,20 @@ bool RagePhoto::load()
return false; return false;
p_jsonBuffer = charToUInt32LE(uInt32Buffer); p_jsonBuffer = charToUInt32LE(uInt32Buffer);
char jsonBytes[p_jsonBuffer]; char *jsonBytes = static_cast<char*>(malloc(p_jsonBuffer));
size = dataBuffer.read(jsonBytes, p_jsonBuffer); if (!jsonBytes)
if (size != p_jsonBuffer)
return false; return false;
size = dataBuffer.read(jsonBytes, p_jsonBuffer);
if (size != p_jsonBuffer) {
free(jsonBytes);
return false;
}
for (quint32 i = 0; i != p_jsonBuffer; i++) { for (quint32 i = 0; i != p_jsonBuffer; i++) {
if (jsonBytes[i] == '\x00') if (jsonBytes[i] == '\x00')
break; break;
p_jsonData += jsonBytes[i]; p_jsonData += jsonBytes[i];
} }
free(jsonBytes);
QJsonDocument t_jsonDocument = QJsonDocument::fromJson(p_jsonData); QJsonDocument t_jsonDocument = QJsonDocument::fromJson(p_jsonData);
if (t_jsonDocument.isNull()) if (t_jsonDocument.isNull())
return false; return false;
@ -186,15 +201,20 @@ bool RagePhoto::load()
return false; return false;
p_titlBuffer = charToUInt32LE(uInt32Buffer); p_titlBuffer = charToUInt32LE(uInt32Buffer);
char titlBytes[p_titlBuffer]; char *titlBytes = static_cast<char*>(malloc(p_titlBuffer));
size = dataBuffer.read(titlBytes, p_titlBuffer); if (!titlBytes)
if (size != p_titlBuffer)
return false; return false;
size = dataBuffer.read(titlBytes, p_titlBuffer);
if (size != p_titlBuffer){
free(titlBytes);
return false;
}
for (const QChar &titlChar : QString::fromUtf8(titlBytes, p_titlBuffer)) { for (const QChar &titlChar : QString::fromUtf8(titlBytes, p_titlBuffer)) {
if (titlChar.isNull()) if (titlChar.isNull())
break; break;
p_titleString += titlChar; p_titleString += titlChar;
} }
free(titlBytes);
dataBuffer.seek(p_descOffset + 264); dataBuffer.seek(p_descOffset + 264);
size = dataBuffer.read(markerBuffer, 4); size = dataBuffer.read(markerBuffer, 4);
@ -208,15 +228,20 @@ bool RagePhoto::load()
return false; return false;
p_descBuffer = charToUInt32LE(uInt32Buffer); p_descBuffer = charToUInt32LE(uInt32Buffer);
char descBytes[p_descBuffer]; char *descBytes = static_cast<char*>(malloc(p_descBuffer));
size = dataBuffer.read(descBytes, p_descBuffer); if (!descBytes)
if (size != p_descBuffer)
return false; return false;
size = dataBuffer.read(descBytes, p_descBuffer);
if (size != p_descBuffer) {
free(descBytes);
return false;
}
for (const QChar &descChar : QString::fromUtf8(descBytes, p_descBuffer)) { for (const QChar &descChar : QString::fromUtf8(descBytes, p_descBuffer)) {
if (descChar.isNull()) if (descChar.isNull())
break; break;
p_descriptionString += descChar; p_descriptionString += descChar;
} }
free(descBytes);
dataBuffer.seek(p_endOfFile + 260); dataBuffer.seek(p_endOfFile + 260);
size = dataBuffer.read(markerBuffer, 4); size = dataBuffer.read(markerBuffer, 4);
@ -243,12 +268,17 @@ bool RagePhoto::load()
return false; return false;
quint32 compressedSize = charToUInt32LE(uInt32Buffer); quint32 compressedSize = charToUInt32LE(uInt32Buffer);
char compressedPhotoHeader[compressedSize]; char *compressedPhotoHeader = static_cast<char*>(malloc(compressedSize));
size = dataBuffer.read(compressedPhotoHeader, compressedSize); if (!compressedPhotoHeader)
if (size != compressedSize)
return false; return false;
size = dataBuffer.read(compressedPhotoHeader, compressedSize);
if (size != compressedSize) {
free(compressedPhotoHeader);
return false;
}
QByteArray t_photoHeader = QByteArray::fromRawData(compressedPhotoHeader, compressedSize); QByteArray t_photoHeader = QByteArray::fromRawData(compressedPhotoHeader, compressedSize);
t_photoHeader = qUncompress(t_photoHeader); t_photoHeader = qUncompress(t_photoHeader);
free(compressedPhotoHeader);
if (t_photoHeader.isEmpty()) if (t_photoHeader.isEmpty())
return false; return false;
p_photoString = QString::fromUtf8(t_photoHeader); p_photoString = QString::fromUtf8(t_photoHeader);
@ -268,12 +298,17 @@ bool RagePhoto::load()
return false; return false;
compressedSize = charToUInt32LE(uInt32Buffer); compressedSize = charToUInt32LE(uInt32Buffer);
char compressedPhoto[compressedSize]; char *compressedPhoto = static_cast<char*>(malloc(compressedSize));
size = dataBuffer.read(compressedPhoto, compressedSize); if (!compressedPhoto)
if (size != compressedSize)
return false; return false;
size = dataBuffer.read(compressedPhoto, compressedSize);
if (size != compressedSize) {
free(compressedPhoto);
return false;
}
QByteArray t_photoData = QByteArray::fromRawData(compressedPhoto, compressedSize); QByteArray t_photoData = QByteArray::fromRawData(compressedPhoto, compressedSize);
p_photoData = qUncompress(t_photoData); p_photoData = qUncompress(t_photoData);
free(compressedPhoto);
size = dataBuffer.read(uInt32Buffer, 4); size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4) if (size != 4)
@ -290,12 +325,17 @@ bool RagePhoto::load()
return false; return false;
compressedSize = charToUInt32LE(uInt32Buffer); compressedSize = charToUInt32LE(uInt32Buffer);
char compressedJson[compressedSize]; char *compressedJson = static_cast<char*>(malloc(compressedSize));
size = dataBuffer.read(compressedJson, compressedSize); if (!compressedJson)
if (size != compressedSize)
return false; return false;
size = dataBuffer.read(compressedJson, compressedSize);
if (size != compressedSize) {
free(compressedJson);
return false;
}
QByteArray t_jsonBytes = QByteArray::fromRawData(compressedJson, compressedSize); QByteArray t_jsonBytes = QByteArray::fromRawData(compressedJson, compressedSize);
p_jsonData = qUncompress(t_jsonBytes); p_jsonData = qUncompress(t_jsonBytes);
free(compressedJson);
if (p_jsonData.isEmpty()) if (p_jsonData.isEmpty())
return false; return false;
QJsonDocument t_jsonDocument = QJsonDocument::fromJson(p_jsonData); QJsonDocument t_jsonDocument = QJsonDocument::fromJson(p_jsonData);
@ -318,12 +358,17 @@ bool RagePhoto::load()
return false; return false;
compressedSize = charToUInt32LE(uInt32Buffer); compressedSize = charToUInt32LE(uInt32Buffer);
char compressedTitl[compressedSize]; char *compressedTitl = static_cast<char*>(malloc(compressedSize));
size = dataBuffer.read(compressedTitl, compressedSize); if (!compressedTitl)
if (size != compressedSize)
return false; return false;
size = dataBuffer.read(compressedTitl, compressedSize);
if (size != compressedSize) {
free(compressedTitl);
return false;
}
QByteArray t_titlBytes = QByteArray::fromRawData(compressedTitl, compressedSize); QByteArray t_titlBytes = QByteArray::fromRawData(compressedTitl, compressedSize);
t_titlBytes = qUncompress(t_titlBytes); t_titlBytes = qUncompress(t_titlBytes);
free(compressedTitl);
p_titleString = QString::fromUtf8(t_titlBytes); p_titleString = QString::fromUtf8(t_titlBytes);
size = dataBuffer.read(uInt32Buffer, 4); size = dataBuffer.read(uInt32Buffer, 4);
@ -341,12 +386,17 @@ bool RagePhoto::load()
return false; return false;
compressedSize = charToUInt32LE(uInt32Buffer); compressedSize = charToUInt32LE(uInt32Buffer);
char compressedDesc[compressedSize]; char *compressedDesc = static_cast<char*>(malloc(compressedSize));
size = dataBuffer.read(compressedDesc, compressedSize); if (!compressedDesc)
if (size != compressedSize)
return false; return false;
size = dataBuffer.read(compressedDesc, compressedSize);
if (size != compressedSize) {
free(compressedDesc);
return false;
}
QByteArray t_descBytes = QByteArray::fromRawData(compressedDesc, compressedSize); QByteArray t_descBytes = QByteArray::fromRawData(compressedDesc, compressedSize);
t_descBytes = qUncompress(t_descBytes); t_descBytes = qUncompress(t_descBytes);
free(compressedDesc);
p_descriptionString = QString::fromUtf8(t_descBytes); p_descriptionString = QString::fromUtf8(t_descBytes);
size = dataBuffer.read(uInt32Buffer, 4); size = dataBuffer.read(uInt32Buffer, 4);
@ -382,7 +432,7 @@ bool RagePhoto::load()
size = dataBuffer.read(length, 1); size = dataBuffer.read(length, 1);
if (size != 1) if (size != 1)
return false; return false;
int i_length = QByteArray::number((int)length[0], 16).toInt() + 6; int i_length = QByteArray::number(static_cast<int>(length[0]), 16).toInt() + 6;
#if QT_VERSION >= 0x050A00 #if QT_VERSION >= 0x050A00
size = dataBuffer.skip(i_length); size = dataBuffer.skip(i_length);