Qt: Fix potential crash when configuring shortcuts

This commit is contained in:
Vicki Pfau 2024-04-24 23:19:31 -07:00
parent 88a8f80ebd
commit 87653b7b19
3 changed files with 29 additions and 24 deletions

View File

@ -22,6 +22,7 @@ Other fixes:
- GB: Fix uninitialized save data when loading undersized temporary saves - GB: Fix uninitialized save data when loading undersized temporary saves
- GBA Memory: Let raw access read high MMIO addresses - GBA Memory: Let raw access read high MMIO addresses
- Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560)
- Qt: Fix potential crash when configuring shortcuts
- Updater: Fix updating appimage across filesystems - Updater: Fix updating appimage across filesystems
Misc: Misc:
- Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826)

View File

@ -28,11 +28,11 @@ QVariant ShortcutModel::data(const QModelIndex& index, int role) const {
if (role != Qt::DisplayRole || !index.isValid()) { if (role != Qt::DisplayRole || !index.isValid()) {
return QVariant(); return QVariant();
} }
const Item* item = static_cast<Item*>(index.internalPointer()); const Item& item = m_cache[index.internalId()];
const Shortcut* shortcut = item->shortcut; const Shortcut* shortcut = item.shortcut;
switch (index.column()) { switch (index.column()) {
case 0: case 0:
return m_controller->visibleName(item->name); return m_controller->visibleName(item.name);
case 1: case 1:
return shortcut ? keyName(shortcut->shortcut()) : QVariant(); return shortcut ? keyName(shortcut->shortcut()) : QVariant();
case 2: case 2:
@ -77,28 +77,31 @@ QVariant ShortcutModel::headerData(int section, Qt::Orientation orientation, int
QModelIndex ShortcutModel::index(int row, int column, const QModelIndex& parent) const { QModelIndex ShortcutModel::index(int row, int column, const QModelIndex& parent) const {
QString pmenu; QString pmenu;
if (parent.isValid()) { if (parent.isValid()) {
pmenu = static_cast<Item*>(parent.internalPointer())->name; const Item& item = m_cache[parent.internalId()];
pmenu = item.name;
} }
QString name = m_controller->name(row, pmenu); QString name = m_controller->name(row, pmenu);
Item* item = &m_cache[name]; size_t hash = qHash(name);
item->name = name; Item& item = m_cache[hash];
item->shortcut = m_controller->shortcut(name); item.name = name;
return createIndex(row, column, item); item.shortcut = m_controller->shortcut(name);
return createIndex(row, column, hash);
} }
QModelIndex ShortcutModel::parent(const QModelIndex& index) const { QModelIndex ShortcutModel::parent(const QModelIndex& index) const {
if (!index.isValid() || !index.internalPointer()) { if (!index.isValid() || !index.internalPointer()) {
return QModelIndex(); return QModelIndex();
} }
Item* item = static_cast<Item*>(index.internalPointer()); const Item& item = m_cache[index.internalId()];
QString parent = m_controller->parent(item->name); QString parent = m_controller->parent(item.name);
if (parent.isNull()) { if (parent.isNull()) {
return QModelIndex(); return QModelIndex();
} }
Item* pitem = &m_cache[parent]; size_t hash = qHash(parent);
pitem->name = parent; Item& pitem = m_cache[hash];
pitem->shortcut = m_controller->shortcut(parent); pitem.name = parent;
return createIndex(m_controller->indexIn(parent), 0, pitem); pitem.shortcut = m_controller->shortcut(parent);
return createIndex(m_controller->indexIn(parent), 0, hash);
} }
int ShortcutModel::columnCount(const QModelIndex&) const { int ShortcutModel::columnCount(const QModelIndex&) const {
@ -109,25 +112,26 @@ int ShortcutModel::rowCount(const QModelIndex& index) const {
if (!index.isValid()) { if (!index.isValid()) {
return m_controller->count(); return m_controller->count();
} }
Item* item = static_cast<Item*>(index.internalPointer()); const Item& item = m_cache[index.internalId()];
return m_controller->count(item->name); return m_controller->count(item.name);
} }
QString ShortcutModel::name(const QModelIndex& index) const { QString ShortcutModel::name(const QModelIndex& index) const {
if (!index.isValid()) { if (!index.isValid()) {
return {}; return {};
} }
Item* item = static_cast<Item*>(index.internalPointer()); const Item& item = m_cache[index.internalId()];
return item->name; return item.name;
} }
void ShortcutModel::addRowNamed(const QString& name) { void ShortcutModel::addRowNamed(const QString& name) {
QString parent = m_controller->parent(name); QString parent = m_controller->parent(name);
Item* item = &m_cache[parent]; size_t hash = qHash(name);
item->name = parent; Item& item = m_cache[hash];
item->shortcut = m_controller->shortcut(parent); item.name = parent;
item.shortcut = m_controller->shortcut(parent);
int index = m_controller->indexIn(name); int index = m_controller->indexIn(name);
beginInsertRows(createIndex(m_controller->indexIn(parent), 0, item), index, index + 1); beginInsertRows(createIndex(m_controller->indexIn(parent), 0, hash), index, index + 1);
endInsertRows(); endInsertRows();
} }

View File

@ -44,7 +44,7 @@ private:
const Shortcut* shortcut = nullptr; const Shortcut* shortcut = nullptr;
}; };
mutable QHash<QString, Item> m_cache; mutable QHash<size_t, Item> m_cache;
}; };
} }