summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Lubomir I. Ivanov <neolit123@gmail.com>2017-10-03 23:16:15 +0300
committerGravatar Dirk Hohndel <dirk@hohndel.org>2017-10-03 15:43:03 -0700
commite3118d915cf49de4cc722522031b0be44014d790 (patch)
treeb811197cc821adcd676eec408ba3ff6d296f54ad
parent53c1c3f26bec6bf1d9f5417d5db12ea532c6a5cc (diff)
downloadsubsurface-e3118d915cf49de4cc722522031b0be44014d790.tar.gz
divelist: prevent a crash for missing column width
The `static int defaultWidth[]` definition in divelistview.cpp could potentially end up missing an element which can later result in out-of-bounds access when iterating through the list of columns and updating their widths. Add a couple of methods in DiveTripModel for setting and getting the widths and use those. The default values are now pre-set in a QVector in the DiveTripModel() constructor. Throw warnings if out-of-bounds columns are requested. Reported-by: Gaetan Bisson <bisson@archlinux.org> Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
-rw-r--r--desktop-widgets/divelistview.cpp13
-rw-r--r--desktop-widgets/divelistview.h1
-rw-r--r--qt-models/divetripmodel.cpp31
-rw-r--r--qt-models/divetripmodel.h3
4 files changed, 40 insertions, 8 deletions
diff --git a/desktop-widgets/divelistview.cpp b/desktop-widgets/divelistview.cpp
index a92afadbd..0b6386efd 100644
--- a/desktop-widgets/divelistview.cpp
+++ b/desktop-widgets/divelistview.cpp
@@ -25,9 +25,6 @@
#include "core/metrics.h"
#include "core/helpers.h"
-// # Date Rtg Dpth Dur Tmp Wght Suit Cyl Gas SAC OTU CNS Px Loc
-static int defaultWidth[] = { 70, 140, 90, 50, 50, 50, 50, 70, 50, 50, 70, 50, 50, 5, 500};
-
DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelection(false), sortColumn(0),
currentOrder(Qt::DescendingOrder), dontEmitDiveChangedSignal(false), selectionSaved(false)
{
@@ -58,7 +55,7 @@ DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelec
// TODO FIXME we need this to get the header names
// can we find a smarter way?
- DiveTripModel *tripModel = new DiveTripModel(this);
+ tripModel = new DiveTripModel(this);
// set the default width as a minimum between the hard-coded defaults,
// the header text width and the (assumed) content width, calculated
@@ -94,8 +91,8 @@ DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelec
if (sw > width)
width = sw;
width += zw; // small padding
- if (width > defaultWidth[col])
- defaultWidth[col] = width;
+ if (width > tripModel->columnWidth(col))
+ tripModel->setColumnWidth(col, width);
}
delete tripModel;
@@ -114,7 +111,7 @@ DiveListView::~DiveListView()
if (isColumnHidden(i))
continue;
// we used to hardcode them all to 100 - so that might still be in the settings
- if (columnWidth(i) == 100 || columnWidth(i) == defaultWidth[i])
+ if (columnWidth(i) == 100 || columnWidth(i) == tripModel->columnWidth(i))
settings.remove(QString("colwidth%1").arg(i));
else
settings.setValue(QString("colwidth%1").arg(i), columnWidth(i));
@@ -140,7 +137,7 @@ void DiveListView::setupUi()
if (width.isValid())
setColumnWidth(i, width.toInt());
else
- setColumnWidth(i, defaultWidth[i]);
+ setColumnWidth(i, tripModel->columnWidth(i));
}
settings.endGroup();
if (firstRun)
diff --git a/desktop-widgets/divelistview.h b/desktop-widgets/divelistview.h
index 5081c8a07..7d3b78cc1 100644
--- a/desktop-widgets/divelistview.h
+++ b/desktop-widgets/divelistview.h
@@ -70,6 +70,7 @@ private:
QModelIndex contextMenuIndex;
bool dontEmitDiveChangedSignal;
bool selectionSaved;
+ DiveTripModel *tripModel;
/* if dive_trip_t is null, there's no problem. */
QMultiHash<dive_trip_t *, int> selectedDives;
diff --git a/qt-models/divetripmodel.cpp b/qt-models/divetripmodel.cpp
index 4082fa989..5777ae88a 100644
--- a/qt-models/divetripmodel.cpp
+++ b/qt-models/divetripmodel.cpp
@@ -6,6 +6,7 @@
#include "core/helpers.h"
#include "core/dive.h"
#include <QIcon>
+#include <QDebug>
static int nitrox_sort_value(struct dive *dive)
{
@@ -407,6 +408,18 @@ DiveTripModel::DiveTripModel(QObject *parent) :
currentLayout(TREE)
{
columns = COLUMNS;
+ // setup the default width of columns (px)
+ columnWidthMap = QVector<int>(COLUMNS);
+ // pre-fill with 50px; the rest are explicit
+ for(int i = 0; i < COLUMNS; i++)
+ columnWidthMap[i] = 50;
+ columnWidthMap[NR] = 70;
+ columnWidthMap[DATE] = 140;
+ columnWidthMap[RATING] = 90;
+ columnWidthMap[SUIT] = 70;
+ columnWidthMap[SAC] = 70;
+ columnWidthMap[PHOTOS] = 5;
+ columnWidthMap[LOCATION] = 500;
}
Qt::ItemFlags DiveTripModel::flags(const QModelIndex &index) const
@@ -605,3 +618,21 @@ bool DiveTripModel::setData(const QModelIndex &index, const QVariant &value, int
return false;
return diveItem->setData(index, value, role);
}
+
+int DiveTripModel::columnWidth(int column)
+{
+ if (column > COLUMNS - 1 || column < 0) {
+ qWarning() << "DiveTripModel::columnWidth(): not a valid column index -" << column;
+ return 50;
+ }
+ return columnWidthMap[column];
+}
+
+void DiveTripModel::setColumnWidth(int column, int width)
+{
+ if (column > COLUMNS - 1 || column < 0) {
+ qWarning() << "DiveTripModel::setColumnWidth(): not a valid column index -" << column;
+ return;
+ }
+ columnWidthMap[column] = width;
+}
diff --git a/qt-models/divetripmodel.h b/qt-models/divetripmodel.h
index ce508a5b5..24b215129 100644
--- a/qt-models/divetripmodel.h
+++ b/qt-models/divetripmodel.h
@@ -94,10 +94,13 @@ public:
DiveTripModel(QObject *parent = 0);
Layout layout() const;
void setLayout(Layout layout);
+ int columnWidth(int column);
+ void setColumnWidth(int column, int width);
private:
void setupModelData();
QMap<dive_trip_t *, TripItem *> trips;
+ QVector<int> columnWidthMap;
Layout currentLayout;
};