Skip to content

Commit af0a949

Browse files
authored
Simplify load file procedure for GeoIP database
PR #24503.
1 parent be46f7f commit af0a949

2 files changed

Lines changed: 37 additions & 54 deletions

File tree

src/base/net/geoipdatabase.cpp

Lines changed: 34 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828

2929
#include "geoipdatabase.h"
3030

31-
#include <QByteArray>
3231
#include <QDateTime>
3332
#include <QDebug>
3433
#include <QFile>
@@ -37,11 +36,12 @@
3736

3837
#include "base/global.h"
3938
#include "base/path.h"
39+
#include "base/utils/io.h"
4040

4141
namespace
4242
{
43-
const qint32 MAX_FILE_SIZE = 67108864; // 64MB
44-
const quint32 MAX_METADATA_SIZE = 131072; // 128KB
43+
const qint32 MAX_FILE_SIZE = 64 * 1024 * 1024;
44+
const quint32 MAX_METADATA_SIZE = 128 * 1024;
4545
const QByteArray METADATA_BEGIN_MARK = QByteArrayLiteral("\xab\xcd\xefMaxMind.com");
4646
const char DATA_SECTION_SEPARATOR[16] = {0};
4747

@@ -76,39 +76,30 @@ struct DataFieldDescriptor
7676
};
7777
};
7878

79-
GeoIPDatabase::GeoIPDatabase(const quint32 size)
80-
: m_size(size)
81-
, m_data(new uchar[size])
79+
GeoIPDatabase::GeoIPDatabase(const QByteArray &data)
80+
: m_data {data}
8281
{
8382
}
8483

8584
GeoIPDatabase *GeoIPDatabase::load(const Path &filename, QString &error)
8685
{
87-
QFile file {filename.data()};
86+
error.clear();
8887

89-
if (!file.open(QFile::ReadOnly))
88+
const auto readResult = Utils::IO::readFile(filename, MAX_FILE_SIZE);
89+
if (!readResult)
9090
{
91-
error = file.errorString();
91+
error = readResult.error().message;
9292
return nullptr;
9393
}
9494

95-
const qint64 fileSize = file.size();
96-
if ((fileSize <= 0) || (fileSize > MAX_FILE_SIZE))
95+
const QByteArray &data = readResult.value();
96+
if (data.size() <= 0)
9797
{
9898
error = tr("Unsupported database file size.");
9999
return nullptr;
100100
}
101101

102-
auto *db = new GeoIPDatabase(static_cast<quint32>(fileSize));
103-
104-
if (file.read(reinterpret_cast<char *>(db->m_data), fileSize) != fileSize)
105-
{
106-
error = file.errorString();
107-
delete db;
108-
return nullptr;
109-
}
110-
111-
102+
auto *db = new GeoIPDatabase(data);
112103
if (!db->parseMetadata(db->readMetadata(), error) || !db->loadDB(error))
113104
{
114105
delete db;
@@ -120,17 +111,16 @@ GeoIPDatabase *GeoIPDatabase::load(const Path &filename, QString &error)
120111

121112
GeoIPDatabase *GeoIPDatabase::load(const QByteArray &data, QString &error)
122113
{
123-
const qint64 dataSize = data.size();
114+
error.clear();
115+
116+
const qsizetype dataSize = data.size();
124117
if ((dataSize <= 0) || (dataSize > MAX_FILE_SIZE))
125118
{
126119
error = tr("Unsupported database file size.");
127120
return nullptr;
128121
}
129122

130-
auto *db = new GeoIPDatabase(static_cast<quint32>(dataSize));
131-
132-
memcpy(reinterpret_cast<char *>(db->m_data), data.constData(), dataSize);
133-
123+
auto *db = new GeoIPDatabase(data);
134124
if (!db->parseMetadata(db->readMetadata(), error) || !db->loadDB(error))
135125
{
136126
delete db;
@@ -140,11 +130,6 @@ GeoIPDatabase *GeoIPDatabase::load(const QByteArray &data, QString &error)
140130
return db;
141131
}
142132

143-
GeoIPDatabase::~GeoIPDatabase()
144-
{
145-
delete [] m_data;
146-
}
147-
148133
QString GeoIPDatabase::type() const
149134
{
150135
return m_dbType;
@@ -164,7 +149,7 @@ QString GeoIPDatabase::lookup(const QHostAddress &hostAddr) const
164149
{
165150
Q_IPV6ADDR addr = hostAddr.toIPv6Address();
166151

167-
const uchar *ptr = m_data;
152+
auto *ptr = reinterpret_cast<const uchar *>(m_data.constData());
168153

169154
for (int i = 0; i < 16; ++i)
170155
{
@@ -201,7 +186,7 @@ QString GeoIPDatabase::lookup(const QHostAddress &hostAddr) const
201186
return country;
202187
}
203188

204-
ptr = m_data + (id * m_nodeSize);
189+
ptr = reinterpret_cast<const uchar *>(m_data.constData()) + (id * m_nodeSize);
205190
}
206191
}
207192

@@ -287,9 +272,10 @@ bool GeoIPDatabase::loadDB(QString &error) const
287272

288273
const int nodeSize = m_recordSize / 4; // in bytes
289274
const int indexSize = m_nodeCount * nodeSize;
290-
if ((m_size < (indexSize + sizeof(DATA_SECTION_SEPARATOR)))
291-
|| (memcmp(m_data + indexSize, DATA_SECTION_SEPARATOR, sizeof(DATA_SECTION_SEPARATOR)) != 0))
292-
{
275+
const int totalSize = indexSize + sizeof(DATA_SECTION_SEPARATOR);
276+
if ((m_data.size() < totalSize)
277+
|| (memcmp((m_data.constData() + indexSize), DATA_SECTION_SEPARATOR, sizeof(DATA_SECTION_SEPARATOR)) != 0))
278+
{
293279
error = tr("Database corrupted: no data section found.");
294280
return false;
295281
}
@@ -299,20 +285,20 @@ bool GeoIPDatabase::loadDB(QString &error) const
299285

300286
QVariantHash GeoIPDatabase::readMetadata() const
301287
{
302-
const char *ptr = reinterpret_cast<const char *>(m_data);
303-
quint32 size = m_size;
304-
if (m_size > MAX_METADATA_SIZE)
288+
const char *ptr = m_data.constData();
289+
qsizetype size = m_data.size();
290+
if (m_data.size() > MAX_METADATA_SIZE)
305291
{
306-
ptr += m_size - MAX_METADATA_SIZE;
292+
ptr += m_data.size() - MAX_METADATA_SIZE;
307293
size = MAX_METADATA_SIZE;
308294
}
309295

310296
const QByteArray data = QByteArray::fromRawData(ptr, size);
311297
qsizetype index = data.lastIndexOf(METADATA_BEGIN_MARK);
312298
if (index >= 0)
313299
{
314-
if (m_size > MAX_METADATA_SIZE)
315-
index += (m_size - MAX_METADATA_SIZE); // from begin of all data
300+
if (m_data.size() > MAX_METADATA_SIZE)
301+
index += (m_data.size() - MAX_METADATA_SIZE); // from begin of all data
316302
auto offset = static_cast<quint32>(index + METADATA_BEGIN_MARK.size());
317303
const QVariant metadata = readDataField(offset);
318304
if (metadata.userType() == QMetaType::QVariantHash)
@@ -346,7 +332,7 @@ QVariant GeoIPDatabase::readDataField(quint32 &offset) const
346332
qDebug() << "* Illegal Pointer using";
347333
break;
348334
case DataType::String:
349-
fieldValue = QString::fromUtf8(reinterpret_cast<const char *>(m_data + locOffset), descr.fieldSize);
335+
fieldValue = QString::fromUtf8((m_data.constData() + locOffset), descr.fieldSize);
350336
locOffset += descr.fieldSize;
351337
break;
352338
case DataType::Double:
@@ -356,7 +342,7 @@ QVariant GeoIPDatabase::readDataField(quint32 &offset) const
356342
qDebug() << "* Invalid field size for type: Double";
357343
break;
358344
case DataType::Bytes:
359-
fieldValue = QByteArray(reinterpret_cast<const char *>(m_data + locOffset), descr.fieldSize);
345+
fieldValue = QByteArray((m_data.constData() + locOffset), descr.fieldSize);
360346
locOffset += descr.fieldSize;
361347
break;
362348
case DataType::Integer16:
@@ -406,8 +392,8 @@ QVariant GeoIPDatabase::readDataField(quint32 &offset) const
406392

407393
bool GeoIPDatabase::readDataFieldDescriptor(quint32 &offset, DataFieldDescriptor &out) const
408394
{
409-
const uchar *dataPtr = m_data + offset;
410-
const int availSize = m_size - offset;
395+
auto *dataPtr = reinterpret_cast<const uchar *>(m_data.constData()) + offset;
396+
const qsizetype availSize = m_data.size() - offset;
411397
if (availSize < 1) return false;
412398

413399
out.fieldType = static_cast<DataType>((dataPtr[0] & 0xE0) >> 5);
@@ -514,8 +500,8 @@ template <typename T>
514500
QVariant GeoIPDatabase::readPlainValue(quint32 &offset, const quint8 len) const
515501
{
516502
T value = 0;
517-
const uchar *const data = m_data + offset;
518-
const quint32 availSize = m_size - offset;
503+
auto *const data = reinterpret_cast<const uchar *>(m_data.constData()) + offset;
504+
const qsizetype availSize = m_data.size() - offset;
519505

520506
if ((len > 0) && (len <= sizeof(T) && (availSize >= len)))
521507
{

src/base/net/geoipdatabase.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@
2929
#pragma once
3030

3131
#include <QtTypes>
32+
#include <QByteArray>
3233
#include <QCoreApplication>
3334
#include <QDateTime>
3435
#include <QHash>
3536
#include <QVariant>
3637

3738
#include "base/pathfwd.h"
3839

39-
class QByteArray;
4040
class QHostAddress;
4141
class QString;
4242

@@ -51,15 +51,13 @@ class GeoIPDatabase
5151
static GeoIPDatabase *load(const Path &filename, QString &error);
5252
static GeoIPDatabase *load(const QByteArray &data, QString &error);
5353

54-
~GeoIPDatabase();
55-
5654
QString type() const;
5755
quint16 ipVersion() const;
5856
QDateTime buildEpoch() const;
5957
QString lookup(const QHostAddress &hostAddr) const;
6058

6159
private:
62-
explicit GeoIPDatabase(quint32 size);
60+
GeoIPDatabase(const QByteArray &data);
6361

6462
bool parseMetadata(const QVariantHash &metadata, QString &error);
6563
bool loadDB(QString &error) const;
@@ -84,6 +82,5 @@ class GeoIPDatabase
8482
QString m_dbType;
8583
// Search data
8684
mutable QHash<quint32, QString> m_countries;
87-
quint32 m_size = 0;
88-
uchar *m_data = nullptr;
85+
const QByteArray m_data;
8986
};

0 commit comments

Comments
 (0)