add a limit to the size of deckfiles cockatrice can load

the limit is 99999 or 100k -1 right now, which is kind of the limit of
what looks acceptable in the player
This commit is contained in:
ebbit1q 2026-08-23 02:25:06 +02:00 • committed by ZeldaZach
parent 6b5105eecc
commit 98ecad9cc5
No known key found for this signature in database
7 changed files with 26 additions and 16 deletions

View file

@ -5,6 +5,8 @@
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QSet> #include <QSet>
static constexpr int MAX_DECK_SIZE = 99999;
DecklistNodeTree::DecklistNodeTree() : root(new InnerDecklistNode()) DecklistNodeTree::DecklistNodeTree() : root(new InnerDecklistNode())
{ {
} }
@ -107,7 +109,7 @@ void DecklistNodeTree::readZoneElement(QXmlStreamReader *xml)
{ {
QString zoneName = xml->attributes().value("name").toString(); QString zoneName = xml->attributes().value("name").toString();
InnerDecklistNode *newZone = getZoneObjFromName(zoneName); InnerDecklistNode *newZone = getZoneObjFromName(zoneName);
newZone->readElement(xml); totalCards += newZone->readElement(xml, MAX_DECK_SIZE - totalCards);
} }
DecklistCardNode *DecklistNodeTree::addCard(const QString &cardName, DecklistCardNode *DecklistNodeTree::addCard(const QString &cardName,
@ -119,6 +121,8 @@ DecklistCardNode *DecklistNodeTree::addCard(const QString &cardName,
const QString &cardProviderId, const QString &cardProviderId,
const bool formatLegal) const bool formatLegal)
{ {
amount = qMin(amount, MAX_DECK_SIZE - totalCards);
totalCards += amount;
auto *zoneNode = getZoneObjFromName(zoneName); auto *zoneNode = getZoneObjFromName(zoneName);
auto *node = new DecklistCardNode(cardName, amount, zoneNode, position, cardSetName, cardSetCollectorNumber, auto *node = new DecklistCardNode(cardName, amount, zoneNode, position, cardSetName, cardSetCollectorNumber,
cardProviderId, formatLegal); cardProviderId, formatLegal);

View file

@ -10,6 +10,7 @@
class DecklistNodeTree class DecklistNodeTree
{ {
InnerDecklistNode *root; ///< Root of the deck tree (zones + cards). InnerDecklistNode *root; ///< Root of the deck tree (zones + cards).
int totalCards = 0;
public: public:
/** @brief Constructs an empty DecklistNodeTree. */ /** @brief Constructs an empty DecklistNodeTree. */

View file

@ -34,15 +34,15 @@ bool AbstractDecklistCardNode::compareName(AbstractDecklistNode *other) const
} }
} }
bool AbstractDecklistCardNode::readElement(QXmlStreamReader *xml) int AbstractDecklistCardNode::readElement(QXmlStreamReader *xml, int /* limit */)
{ {
while (!xml->atEnd()) { while (!xml->atEnd()) {
xml->readNext(); xml->readNext();
if (xml->isEndElement() && xml->name().toString() == "card") { if (xml->isEndElement() && xml->name().toString() == "card") {
return false; return 0;
} }
} }
return true; return 0;
} }
void AbstractDecklistCardNode::writeElement(QXmlStreamWriter *xml) void AbstractDecklistCardNode::writeElement(QXmlStreamWriter *xml)

View file

@ -141,7 +141,7 @@ public:
* *
* This supports loading deck files from Cockatrice’s XML format. * This supports loading deck files from Cockatrice’s XML format.
*/ */
bool readElement(QXmlStreamReader *xml) override; int readElement(QXmlStreamReader *xml, int limit) override;
/** /**
* @brief Serialize this node’s properties to XML. * @brief Serialize this node’s properties to XML.

View file

@ -177,7 +177,7 @@ public:
* Cockatrice deck XML format. * Cockatrice deck XML format.
* @{ * @{
*/ */
virtual bool readElement(QXmlStreamReader *xml) = 0; virtual int readElement(QXmlStreamReader *xml, int limit) = 0;
virtual void writeElement(QXmlStreamWriter *xml) = 0; virtual void writeElement(QXmlStreamWriter *xml) = 0;
/// @} /// @}
}; };

View file

@ -139,27 +139,31 @@ bool InnerDecklistNode::compareName(AbstractDecklistNode *other) const
} }
} }
bool InnerDecklistNode::readElement(QXmlStreamReader *xml) int InnerDecklistNode::readElement(QXmlStreamReader *xml, int limit)
{ {
int totalCards = 0;
while (!xml->atEnd()) { while (!xml->atEnd()) {
xml->readNext(); xml->readNext();
const QString childName = xml->name().toString(); const QString childName = xml->name().toString();
if (xml->isStartElement()) { if (xml->isStartElement()) {
if (childName == "zone") { if (childName == "zone") {
auto *newZone = new InnerDecklistNode(xml->attributes().value("name").toString(), this); auto *newZone = new InnerDecklistNode(xml->attributes().value("name").toString(), this);
newZone->readElement(xml); totalCards += newZone->readElement(xml, limit - totalCards);
} else if (childName == "card") { } else if (childName == "card") {
int amount = xml->attributes().value("number").toString().toInt();
amount = qMin(amount, limit - totalCards);
auto *newCard = new DecklistCardNode( auto *newCard = new DecklistCardNode(
xml->attributes().value("name").toString(), xml->attributes().value("number").toString().toInt(), xml->attributes().value("name").toString(), amount,
this, -1, xml->attributes().value("setShortName").toString(), this, -1, xml->attributes().value("setShortName").toString(),
xml->attributes().value("collectorNumber").toString(), xml->attributes().value("uuid").toString()); xml->attributes().value("collectorNumber").toString(), xml->attributes().value("uuid").toString());
newCard->readElement(xml); totalCards += amount;
totalCards += newCard->readElement(xml, limit - totalCards);
} }
} else if (xml->isEndElement() && (childName == "zone")) { } else if (xml->isEndElement() && (childName == "zone")) {
return false; return totalCards;
} }
} }
return true; return totalCards;
} }
void InnerDecklistNode::writeElement(QXmlStreamWriter *xml) void InnerDecklistNode::writeElement(QXmlStreamWriter *xml)

View file

@ -214,9 +214,10 @@ public:
/** /**
* @brief Deserialize this node and its children from XML. * @brief Deserialize this node and its children from XML.
* @param xml Reader positioned at this element. * @param xml Reader positioned at this element.
* @return true if parsing succeeded. * @param limit The maximum amount of cards to read
* @return the amount of cards found
*/ */
bool readElement(QXmlStreamReader *xml) override; int readElement(QXmlStreamReader *xml, int limit) override;
/** /**
* @brief Serialize this node and its children to XML. * @brief Serialize this node and its children to XML.