Fix StackZone crash when divideCardSpaceInZone overflows (#5751)

The divideCardSpaceInZone function introduced in #4930 is buggy and
sometimes returns an index that is too large for the current zone, which
causes us to call `cards.at(index)` with an `index` that's bigger than
the amount of cards.

This is the bug that #5609 intended to fix but was improperly diagnosed.
Remove part of #5609 as the cases it is guarding against (e.g. null card
pointer) cannot actually happen.
This commit is contained in:
Basile Clement 2025-03-21 01:30:46 +01:00 committed by GitHub
parent 2e01dfd23a
commit 76fa87c63e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 14 additions and 19 deletions

View file

@ -47,12 +47,10 @@
# card_info = false
# card_list = false
# stack_zone = false
flow_layout.debug = false
flow_widget.debug = false
flow_widget.size.debug = false
# pixel_map_generator = false
# filter_string = false
# filter_string = false

View file

@ -66,26 +66,25 @@ void StackZone::handleDropEvent(const QList<CardDragItem *> &dragItems, CardZone
cmd.set_target_zone(getName().toStdString());
int index = 0;
if (cards.isEmpty()) {
index = 0;
} else {
if (!cards.isEmpty()) {
const auto cardCount = static_cast<int>(cards.size());
const auto &card = cards.at(0);
if (card == nullptr) {
qCWarning(StackZoneLog) << "Attempted to move card from" << startZone->getName() << ", but was null";
return;
}
index = qRound(divideCardSpaceInZone(dropPoint.y(), cardCount, boundingRect().height(),
card->boundingRect().height(), true));
}
if (startZone == this) {
const auto &dragItem = dragItems.at(0);
const auto &card = cards.at(index);
if (card != nullptr && dragItem != nullptr && card->getId() == dragItem->getId()) {
return;
// divideCardSpaceInZone is not guaranteed to return a valid index
// currently, so clamp it to avoid crashes.
index = qBound(0, index, cardCount - 1);
if (startZone == this) {
const auto &dragItem = dragItems.at(0);
const auto &card = cards.at(index);
if (card->getId() == dragItem->getId()) {
return;
}
}
}

View file

@ -3,8 +3,6 @@
#include "select_zone.h"
inline Q_LOGGING_CATEGORY(StackZoneLog, "stack_zone");
class StackZone : public SelectZone
{
Q_OBJECT