refactored update info parsing code (again).

This commit is contained in:
LoRd_MuldeR 2018-10-19 00:22:01 +02:00
parent a2e57f2d45
commit 3b63946c96
2 changed files with 67 additions and 107 deletions

View File

@ -135,11 +135,7 @@ namespace MUtils
bool getUpdateInfo(const QString &url, const QString &outFileVers, const QString &outFileSign); bool getUpdateInfo(const QString &url, const QString &outFileVers, const QString &outFileSign);
bool tryContactHost(const QString &hostname, const int &timeoutMsec); bool tryContactHost(const QString &hostname, const int &timeoutMsec);
bool parseVersionInfo(const QString &file, UpdateCheckerInfo *const updateInfo); bool parseVersionInfo(const QString &file, UpdateCheckerInfo *const updateInfo);
int parseSectionHeaderStr(const QString &name);
void parseHeaderValue(const QString &key, const QString &val, QDate &updateInfoDate);
void parseUpdateInfoValue(const QString &key, const QString &val, UpdateCheckerInfo *const updateInfo);
bool getFile(const QUrl &url, const QString &outFile, const unsigned int maxRedir = 8U); bool getFile(const QUrl &url, const QString &outFile, const unsigned int maxRedir = 8U);
bool checkSignature(const QString &file, const QString &signature); bool checkSignature(const QString &file, const QString &signature);

View File

@ -59,6 +59,10 @@ static const int DOWNLOAD_TIMEOUT = 30000;
static const int VERSION_INFO_EXPIRES_MONTHS = 6; static const int VERSION_INFO_EXPIRES_MONTHS = 6;
static char *USER_AGENT_STR = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"; /*use something innocuous*/ static char *USER_AGENT_STR = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"; /*use something innocuous*/
////////////////////////////////////////////////////////////
// Utility Macros
////////////////////////////////////////////////////////////
#define CHECK_CANCELLED() do \ #define CHECK_CANCELLED() do \
{ \ { \
if(MUTILS_BOOLIFY(m_cancelled)) \ if(MUTILS_BOOLIFY(m_cancelled)) \
@ -461,6 +465,43 @@ bool MUtils::UpdateChecker::getUpdateInfo(const QString &url, const QString &out
// PARSE UPDATE INFO // PARSE UPDATE INFO
//---------------------------------------------------------- //----------------------------------------------------------
#define _CHECK_HEADER(ID,NAME) \
if (STRICMP(name, (NAME))) \
{ \
sectionId = (ID); \
continue; \
}
#define _PARSE_TEXT(OUT,KEY) \
if (STRICMP(key, (KEY))) \
{ \
(OUT) = val; \
break; \
}
#define _PARSE_UINT(OUT,KEY) \
if (STRICMP(key, (KEY))) \
{ \
bool _ok = false; \
const unsigned int _tmp = val.toUInt(&_ok); \
if (_ok) \
{ \
(OUT) = _tmp; \
break; \
} \
}
#define _PARSE_DATE(OUT,KEY) \
if (STRICMP(key, (KEY))) \
{ \
const QDate _tmp = QDate::fromString(val, Qt::ISODate); \
if (_tmp.isValid()) \
{ \
(OUT) = _tmp; \
break; \
} \
}
bool MUtils::UpdateChecker::parseVersionInfo(const QString &file, UpdateCheckerInfo *const updateInfo) bool MUtils::UpdateChecker::parseVersionInfo(const QString &file, UpdateCheckerInfo *const updateInfo)
{ {
updateInfo->resetInfo(); updateInfo->resetInfo();
@ -471,7 +512,7 @@ bool MUtils::UpdateChecker::parseVersionInfo(const QString &file, UpdateCheckerI
qWarning("Cannot open update info file for reading!"); qWarning("Cannot open update info file for reading!");
return false; return false;
} }
QDate updateInfoDate; QDate updateInfoDate;
int sectionId = 0; int sectionId = 0;
QRegExp regex_sec("^\\[(.+)\\]$"), regex_val("^([^=]+)=(.+)$"); QRegExp regex_sec("^\\[(.+)\\]$"), regex_val("^([^=]+)=(.+)$");
@ -481,142 +522,65 @@ bool MUtils::UpdateChecker::parseVersionInfo(const QString &file, UpdateCheckerI
QString line = QString::fromLatin1(data.readLine()).trimmed(); QString line = QString::fromLatin1(data.readLine()).trimmed();
if (regex_sec.indexIn(line) >= 0) if (regex_sec.indexIn(line) >= 0)
{ {
sectionId = parseSectionHeaderStr(regex_sec.cap(1).trimmed()); const QString name = regex_sec.cap(1).trimmed();
log(QString("Sec: [%1]").arg(name));
_CHECK_HEADER(1, HEADER_ID)
_CHECK_HEADER(2, m_applicationId)
sectionId = 0;
continue; continue;
} }
if (regex_val.indexIn(line) >= 0) if (regex_val.indexIn(line) >= 0)
{ {
const QString key = regex_val.cap(1).trimmed(); const QString key = regex_val.cap(1).trimmed();
const QString val = regex_val.cap(2).trimmed(); const QString val = regex_val.cap(2).trimmed();
log(QString("Val: \"%1\" = \"%2\"").arg(key, val));
switch (sectionId) switch (sectionId)
{ {
case 1: case 1:
parseHeaderValue(key, val, updateInfoDate); _PARSE_DATE(updateInfoDate, "TimestampCreated")
break; break;
case 2: case 2:
parseUpdateInfoValue(key, val, updateInfo); _PARSE_UINT(updateInfo->m_buildNo, "BuildNo")
_PARSE_DATE(updateInfo->m_buildDate, "BuildDate")
_PARSE_TEXT(updateInfo->m_downloadSite, "DownloadSite")
_PARSE_TEXT(updateInfo->m_downloadAddress, "DownloadAddress")
_PARSE_TEXT(updateInfo->m_downloadFilename, "DownloadFilename")
_PARSE_TEXT(updateInfo->m_downloadFilecode, "DownloadFilecode")
_PARSE_TEXT(updateInfo->m_downloadChecksum, "DownloadChecksum")
break; break;
} }
} }
} }
if (!updateInfo->isComplete())
{
log("", "WARNING: Update information is incomplete!");
goto failure;
}
if(updateInfoDate.isValid()) if(updateInfoDate.isValid())
{ {
const QDate expiredDate = updateInfoDate.addMonths(VERSION_INFO_EXPIRES_MONTHS); const QDate expiredDate = updateInfoDate.addMonths(VERSION_INFO_EXPIRES_MONTHS);
if (expiredDate < OS::current_date()) if (expiredDate < OS::current_date())
{ {
log(QString("WARNING: Update information has expired at %1!").arg(expiredDate.toString(Qt::ISODate))); log("", QString("WARNING: Update information has expired at %1!").arg(expiredDate.toString(Qt::ISODate)));
goto cleanUp; goto failure;
} }
} }
else else
{ {
log("WARNING: Timestamp is missing from update information header!"); log("", "WARNING: Timestamp is missing from update information header!");
goto cleanUp; goto failure;
}
if(!updateInfo->isComplete())
{
log("WARNING: Update information is incomplete!");
goto cleanUp;
} }
log("", "Success: Update information is complete."); log("", "Success: Update information is complete.");
return true; /*success*/ return true; /*success*/
cleanUp: failure:
updateInfo->resetInfo(); updateInfo->resetInfo();
return false; return false;
} }
int MUtils::UpdateChecker::parseSectionHeaderStr(const QString &name)
{
log(QString("Sec: [%1]").arg(name));
if (STRICMP(name, HEADER_ID))
{
return 1;
}
if (STRICMP(name, m_applicationId))
{
return 2;
}
//Unknonw section encountered!
return 0;
}
void MUtils::UpdateChecker::parseHeaderValue(const QString &key, const QString &val, QDate &updateInfoDate)
{
log(QString("Hdr: \"%1\"=\"%2\"").arg(key, val));
if (STRICMP(key, "TimestampCreated"))
{
const QDate temp = QDate::fromString(val, Qt::ISODate);
if (temp.isValid())
{
updateInfoDate = temp;
}
return;
}
//Unknown entry encountered!
qWarning("Unknown header value: %s", MUTILS_L1STR(key));
}
void MUtils::UpdateChecker::parseUpdateInfoValue(const QString &key, const QString &val, UpdateCheckerInfo *const updateInfo)
{
log(QString("Val: \"%1\"=\"%2\"").arg(key, val));
if (STRICMP(key, "BuildNo"))
{
bool ok = false;
const unsigned int temp = val.toUInt(&ok);
if (ok)
{
updateInfo->m_buildNo = temp;
}
return;
}
if (STRICMP(key, "BuildDate"))
{
const QDate temp = QDate::fromString(val, Qt::ISODate);
if (temp.isValid())
{
updateInfo->m_buildDate = temp;
}
return;
}
if (STRICMP(key, "DownloadSite"))
{
updateInfo->m_downloadSite = val;
return;
}
if (STRICMP(key, "DownloadAddress"))
{
updateInfo->m_downloadAddress = val;
return;
}
if (STRICMP(key, "DownloadFilename"))
{
updateInfo->m_downloadFilename = val;
return;
}
if (STRICMP(key, "DownloadFilecode"))
{
updateInfo->m_downloadFilecode = val;
return;
}
if (STRICMP(key, "DownloadChecksum"))
{
updateInfo->m_downloadChecksum = val;
return;
}
//Unknown entry encountered!
qWarning("Unknown update value: %s", MUTILS_L1STR(key));
}
//---------------------------------------------------------- //----------------------------------------------------------
// EXTERNAL TOOLS // EXTERNAL TOOLS
//---------------------------------------------------------- //----------------------------------------------------------