mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-28 13:10:19 +00:00
396b2d1031
DiveComputerList::getExact() created a temporary QList with the DiveComputerNodes matching a specific model. A pointer to a node in the list was returned, which becomes invalid when the list goes out of scope and gets destroyed. Causing a crash when the model strings are compared later. Instead of using contains() and creating a temporary list, we can just use an iterator, which should be both faster and safer. The crash is easy to trigger with DM4 imports, but can probably be triggered in other cases too. Similar problem with DiveComputerList::get(). Signed-off-by: Michael Andreen <harv@ruin.nu> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
78 lines
2.2 KiB
C++
78 lines
2.2 KiB
C++
#include "qthelper.h"
|
|
|
|
DiveComputerList::DiveComputerList()
|
|
{
|
|
|
|
}
|
|
|
|
DiveComputerList::~DiveComputerList()
|
|
{
|
|
|
|
}
|
|
|
|
bool DiveComputerNode::operator == (const DiveComputerNode &a) const {
|
|
return this->model == a.model &&
|
|
this->deviceId == a.deviceId &&
|
|
this->firmware == a.firmware &&
|
|
this->serialNumber == a.serialNumber &&
|
|
this->nickName == a.nickName;
|
|
}
|
|
|
|
bool DiveComputerNode::operator !=(const DiveComputerNode &a) const {
|
|
return !(*this == a);
|
|
}
|
|
|
|
bool DiveComputerNode::changesValues(const DiveComputerNode &b) const
|
|
{
|
|
if (this->model != b.model || this->deviceId != b.deviceId) {
|
|
qDebug("DiveComputerNodes were not for the same DC");
|
|
return false;
|
|
}
|
|
return (b.firmware != "" && this->firmware != b.firmware) ||
|
|
(b.serialNumber != "" && this->serialNumber != b.serialNumber) ||
|
|
(b.nickName != "" && this->nickName != b.nickName);
|
|
}
|
|
|
|
const DiveComputerNode *DiveComputerList::getExact(QString m, uint32_t d)
|
|
{
|
|
for (QMap<QString,DiveComputerNode>::iterator it = dcMap.find(m); it != dcMap.end() && it.key() == m; ++it)
|
|
if (it->deviceId == d)
|
|
return &*it;
|
|
return NULL;
|
|
}
|
|
|
|
const DiveComputerNode *DiveComputerList::get(QString m)
|
|
{
|
|
QMap<QString,DiveComputerNode>::iterator it = dcMap.find(m);
|
|
if (it != dcMap.end())
|
|
return &*it;
|
|
return NULL;
|
|
}
|
|
|
|
void DiveComputerList::addDC(QString m, uint32_t d, QString n, QString s, QString f)
|
|
{
|
|
if (m == "" || d == 0)
|
|
return;
|
|
const DiveComputerNode *existNode = this->getExact(m, d);
|
|
DiveComputerNode newNode(m, d, s, f, n);
|
|
if (existNode) {
|
|
if (newNode.changesValues(*existNode)) {
|
|
if (n != "" && existNode->nickName != n)
|
|
qDebug("new nickname %s for DC model %s deviceId 0x%x", n.toUtf8().data(), m.toUtf8().data(), d);
|
|
if (f != "" && existNode->firmware != f)
|
|
qDebug("new firmware version %s for DC model %s deviceId 0x%x", f.toUtf8().data(), m.toUtf8().data(), d);
|
|
if (s != "" && existNode->serialNumber != s)
|
|
qDebug("new serial number %s for DC model %s deviceId 0x%x", s.toUtf8().data(), m.toUtf8().data(), d);
|
|
} else {
|
|
return;
|
|
}
|
|
dcMap.remove(m, *existNode);
|
|
}
|
|
dcMap.insert(m, newNode);
|
|
}
|
|
|
|
void DiveComputerList::rmDC(QString m, uint32_t d)
|
|
{
|
|
const DiveComputerNode *existNode = this->getExact(m, d);
|
|
dcMap.remove(m, *existNode);
|
|
}
|