Fix API crashes on bad palette ids / tile numbers

This commit is contained in:
GriffinR 2022-07-27 13:39:31 -04:00
parent c88b8b7663
commit 778cc2ba47
5 changed files with 34 additions and 12 deletions

View file

@ -18,6 +18,7 @@ public:
int palette; int palette;
uint16_t rawValue() const; uint16_t rawValue() const;
void sanitize();
static int getIndexInTileset(int); static int getIndexInTileset(int);
}; };

View file

@ -30,6 +30,17 @@ uint16_t Tile::rawValue() const {
| ((this->palette & 0xF) << 12)); | ((this->palette & 0xF) << 12));
} }
void Tile::sanitize() {
if (tileId < 0 || tileId >= Project::getNumTilesTotal()) {
logWarn(QString("Resetting tile's invalid tile id '%1' to 0.").arg(tileId));
tileId = 0;
}
if (palette < 0 || palette >= Project::getNumPalettesTotal()) {
logWarn(QString("Resetting tile's invalid palette id '%1' to 0.").arg(palette));
palette = 0;
}
}
int Tile::getIndexInTileset(int tileId) { int Tile::getIndexInTileset(int tileId) {
if (tileId < Project::getNumTilesPrimary()) { if (tileId < Project::getNumTilesPrimary()) {
return tileId; return tileId;

View file

@ -120,6 +120,12 @@ QList<QRgb> Tileset::getPalette(int paletteId, Tileset *primaryTileset, Tileset
? primaryTileset ? primaryTileset
: secondaryTileset; : secondaryTileset;
auto palettes = useTruePalettes ? tileset->palettes : tileset->palettePreviews; auto palettes = useTruePalettes ? tileset->palettes : tileset->palettePreviews;
if (paletteId < 0 || paletteId >= palettes.length()){
logError(QString("Invalid tileset palette id '%1' requested.").arg(paletteId));
return paletteTable;
}
for (int i = 0; i < palettes.at(paletteId).length(); i++) { for (int i = 0; i < palettes.at(paletteId).length(); i++) {
paletteTable.append(palettes.at(paletteId).at(i)); paletteTable.append(palettes.at(paletteId).at(i));
} }

View file

@ -991,8 +991,11 @@ void MainWindow::setMetatileTiles(int metatileId, QJSValue tilesObj, int tileSta
// Write to metatile using as many of the given Tiles as possible // Write to metatile using as many of the given Tiles as possible
int numTileObjs = qMin(tilesObj.property("length").toInt(), numTiles); int numTileObjs = qMin(tilesObj.property("length").toInt(), numTiles);
int i = 0; int i = 0;
for (; i < numTileObjs; i++, tileStart++) for (; i < numTileObjs; i++, tileStart++) {
metatile->tiles[tileStart] = Scripting::toTile(tilesObj.property(i)); Tile tile = Scripting::toTile(tilesObj.property(i));
tile.sanitize();
metatile->tiles[tileStart] = tile;
}
// Fill remainder of specified length with empty Tiles // Fill remainder of specified length with empty Tiles
for (; i < numTiles; i++, tileStart++) for (; i < numTiles; i++, tileStart++)
@ -1011,6 +1014,7 @@ void MainWindow::setMetatileTiles(int metatileId, int tileId, bool xflip, bool y
// Write to metatile using Tiles of the specified value // Write to metatile using Tiles of the specified value
Tile tile = Tile(tileId, xflip, yflip, palette); Tile tile = Tile(tileId, xflip, yflip, palette);
tile.sanitize();
for (int i = tileStart; i <= tileEnd; i++) for (int i = tileStart; i <= tileEnd; i++)
metatile->tiles[i] = tile; metatile->tiles[i] = tile;

View file

@ -239,17 +239,17 @@ QJSValue Scripting::position(int x, int y) {
} }
Tile Scripting::toTile(QJSValue obj) { Tile Scripting::toTile(QJSValue obj) {
if (!obj.hasProperty("tileId")
|| !obj.hasProperty("xflip")
|| !obj.hasProperty("yflip")
|| !obj.hasProperty("palette")) {
return Tile();
}
Tile tile = Tile(); Tile tile = Tile();
tile.tileId = obj.property("tileId").toInt();
tile.xflip = obj.property("xflip").toBool(); if (obj.hasProperty("tileId"))
tile.yflip = obj.property("yflip").toBool(); tile.tileId = obj.property("tileId").toInt();
tile.palette = obj.property("palette").toInt(); if (obj.hasProperty("xflip"))
tile.xflip = obj.property("xflip").toBool();
if (obj.hasProperty("yflip"))
tile.yflip = obj.property("yflip").toBool();
if (obj.hasProperty("palette"))
tile.palette = obj.property("palette").toInt();
return tile; return tile;
} }