Messagelib

localdatabasefile.cpp
1 /*
2  SPDX-FileCopyrightText: 2016-2021 Laurent Montel <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "localdatabasefile.h"
8 #include "checkphishingurlutil.h"
9 #include "updatedatabaseinfo.h"
10 #include "webengineviewer_debug.h"
11 #include <QDateTime>
12 #include <QElapsedTimer>
13 #include <QFileInfo>
14 
15 using namespace WebEngineViewer;
16 
17 WEBENGINEVIEWER_EXPORT int webengineview_LocalDataBaseFile = 1000 * 60 * 60;
18 
19 class WebEngineViewer::LocalDataBaseFilePrivate
20 {
21 public:
22  LocalDataBaseFilePrivate(const QString &filename, LocalDataBaseFile *qq)
23  : mFile(filename)
24  , q(qq)
25  {
26  }
27 
28  bool load();
29  bool reload();
30  void close();
31 
32  QElapsedTimer mLastCheck;
33  QFile mFile;
34  uchar *mData = nullptr;
35  QDateTime mMtime;
36  LocalDataBaseFile *const q;
37  bool mValid = false;
38 };
39 
40 bool LocalDataBaseFilePrivate::load()
41 {
42  if (!mFile.open(QIODevice::ReadOnly)) {
43  return false;
44  }
45  mData = mFile.map(0, mFile.size());
46  if (mData) {
47  const int major = q->getUint16(0);
48  const int minor = q->getUint16(2);
49 
50  // Check version in binary file. => version value == 1.0 for the moment see CheckPhishingUrlUtil
51  mValid = (major == WebEngineViewer::CheckPhishingUrlUtil::majorVersion() && minor == WebEngineViewer::CheckPhishingUrlUtil::minorVersion());
52  }
53  mMtime = QFileInfo(mFile).lastModified();
54  return mValid;
55 }
56 
57 void LocalDataBaseFilePrivate::close()
58 {
59  mValid = false;
60  if (mFile.isOpen()) {
61  mFile.close();
62  }
63  mData = nullptr;
64 }
65 
66 bool LocalDataBaseFilePrivate::reload()
67 {
68  qCDebug(WEBENGINEVIEWER_LOG) << "Reload File" << mFile.fileName();
69  close();
70  return load();
71 }
72 
73 LocalDataBaseFile::LocalDataBaseFile(const QString &filename)
74  : d(new WebEngineViewer::LocalDataBaseFilePrivate(filename, this))
75 {
76  d->load();
77 }
78 
79 LocalDataBaseFile::~LocalDataBaseFile() = default;
80 
81 void LocalDataBaseFile::close()
82 {
83  d->close();
84 }
85 
86 bool LocalDataBaseFile::isValid() const
87 {
88  return d->mValid;
89 }
90 
91 quint16 LocalDataBaseFile::getUint16(int offset) const
92 {
93  return *reinterpret_cast<quint16 *>(d->mData + offset);
94 }
95 
96 quint32 LocalDataBaseFile::getUint32(int offset) const
97 {
98  return *reinterpret_cast<quint32 *>(d->mData + offset);
99 }
100 
101 quint64 LocalDataBaseFile::getUint64(int offset) const
102 {
103  return *reinterpret_cast<quint64 *>(d->mData + offset);
104 }
105 
106 const char *LocalDataBaseFile::getCharStar(int offset) const
107 {
108  return reinterpret_cast<const char *>(d->mData + offset);
109 }
110 
111 bool LocalDataBaseFile::reload()
112 {
113  return d->reload();
114 }
115 
116 QByteArray LocalDataBaseFile::searchHash(const QByteArray &hashToSearch)
117 {
118  /* database file has:
119  * - one getUint16 => major
120  * - one getUint16 => minor
121  * - one getUint64 => number of item
122  * => 12
123  */
124  int posListOffset = 12;
125  const int numHash = getUint64(4);
126  int end = numHash - 1;
127  QByteArray previousValue;
128  if (end > 0) {
129  QByteArray currentValue;
130  int begin = 0;
131  do {
132  previousValue = currentValue;
133  const int medium = (begin + end) / 2;
134  const int off = posListOffset + 8 * medium;
135  const int hashOffset = getUint64(off);
136  const char *hashCharStar = getCharStar(hashOffset);
137  const int cmp = qstrcmp(hashCharStar, hashToSearch.constData());
138  currentValue = QByteArray(hashCharStar);
139  qCWarning(WEBENGINEVIEWER_LOG) << "search " << hashToSearch.toBase64() << " begin " << begin << " end " << end << " hashCharStar"
140  << currentValue.toBase64();
141  if (end == begin) {
142  return currentValue;
143  }
144  if (cmp < 0) {
145  begin = medium + 1;
146  } else if (cmp > 0) {
147  end = medium - 1;
148  } else {
149  return currentValue;
150  }
151  } while (begin <= end);
152  }
153  return previousValue;
154 }
155 
156 bool LocalDataBaseFile::shouldCheck() const
157 {
158  // 1 hours
159  if (d->mLastCheck.isValid() && d->mLastCheck.elapsed() < webengineview_LocalDataBaseFile) {
160  return false;
161  }
162  d->mLastCheck.start();
163  return true;
164 }
165 
166 bool LocalDataBaseFile::checkFileChanged()
167 {
168  bool somethingChanged = false;
169  QFileInfo fileInfo(d->mFile);
170  if (!fileInfo.exists() || fileInfo.lastModified() > d->mMtime) {
171  // But the user could use rm -rf :-)
172  reload(); // will mark itself as invalid on failure
173  somethingChanged = true;
174  }
175  if (somethingChanged) {
176  return isValid();
177  }
178  return somethingChanged;
179 }
180 
181 QVector<WebEngineViewer::Addition> LocalDataBaseFile::extractAllInfo() const
182 {
184  quint64 numberOfElement = getUint64(4);
185  lst.reserve(numberOfElement);
186  int index = 12; // quint16 major + quint16 minor + quint64 number of element
187  for (quint64 i = 0; i < numberOfElement; ++i) {
188  const quint64 value = getUint64(index);
189  Addition tmp;
190  tmp.hashString = QByteArray(getCharStar(value));
191  tmp.prefixSize = tmp.hashString.size();
192  tmp.compressionType = WebEngineViewer::UpdateDataBaseInfo::RawCompression;
193  index += 8; // next index based on quint64
194  lst.append(tmp);
195  }
196  return lst;
197 }
198 
199 bool LocalDataBaseFile::fileExists() const
200 {
201  QFileInfo fileInfo(d->mFile);
202  return fileInfo.exists();
203 }
void append(const T &value)
const QList< QKeySequence > & close()
const QList< QKeySequence > & begin()
const QList< QKeySequence > & reload()
QAction * load(const QObject *recvr, const char *slot, QObject *parent)
const char * constData() const const
QDateTime lastModified() const const
void reserve(int size)
const QList< QKeySequence > & end()
bool isValid(QStringView ifopt)
QByteArray toBase64(QByteArray::Base64Options options) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Nov 30 2021 23:05:47 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.