From ea8de4df763d406a160707e1fa96d2ded35e4c32 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sat, 22 Nov 2025 14:04:40 -0500 Subject: [PATCH] Fix potential out of bounds map layout read --- CHANGELOG.md | 1 + include/core/maplayout.h | 2 ++ src/editor.cpp | 29 ++++++++++++++--------------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8c30b8b..8452c43d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project somewhat adheres to [Semantic Versioning](https://semver.org/sp - Previously, the middle mouse button could be used as a shortcut with the pencil tool to switch to bucket-fill mode. This is now achieved using the `Alt` key. ### Fixed +- Fix potential crash when painting and the cursor leaves the map area. - Fix rare crash while quitting Porymap. - Fix `Edit > Clear Map Entries` in the Region Map Editor not saving the applied changes. - Fix `Edit > Undo/Redo` appearing enabled even when they don't do anything. diff --git a/include/core/maplayout.h b/include/core/maplayout.h index 92f0264e..3095574b 100644 --- a/include/core/maplayout.h +++ b/include/core/maplayout.h @@ -125,7 +125,9 @@ public: bool isWithinBorderBounds(int x, int y) const; bool getBlock(int x, int y, Block *out) const; + bool getBlock(const QPoint& pos, Block *out) const { return getBlock(pos.x(), pos.y(), out); } void setBlock(int x, int y, Block block, bool enableScriptCallback = false); + void setBlock(const QPoint& pos, Block block, bool enableScriptCallback = false) { setBlock(pos.x(), pos.y(), block, enableScriptCallback); } void setBlockdata(Blockdata blockdata, bool enableScriptCallback = false); uint16_t getMetatileId(int x, int y) const; diff --git a/src/editor.cpp b/src/editor.cpp index 793453e9..6ad57961 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -1244,28 +1244,27 @@ void Editor::onMapHoverCleared() { } void Editor::setStatusFromMapPos(const QPoint &pos) { - int x = pos.x(); - int y = pos.y(); + Block block; + if (!this->layout || !this->layout->getBlock(pos, &block)) { + ui->statusBar->clearMessage(); + return; + } + if (this->editMode == EditMode::Metatiles) { - int blockIndex = y * layout->getWidth() + x; - int metatileId = layout->blockdata.at(blockIndex).metatileId(); this->ui->statusBar->showMessage(QString("X: %1, Y: %2, %3, Scale = %4x") - .arg(x) - .arg(y) - .arg(getMetatileDisplayMessage(metatileId)) + .arg(pos.x()) + .arg(pos.y()) + .arg(getMetatileDisplayMessage(block.metatileId())) .arg(QString::number(zoomLevels[this->scaleIndex], 'g', 2))); } else if (this->editMode == EditMode::Collision) { - int blockIndex = y * layout->getWidth() + x; - uint16_t collision = layout->blockdata.at(blockIndex).collision(); - uint16_t elevation = layout->blockdata.at(blockIndex).elevation(); this->ui->statusBar->showMessage(QString("X: %1, Y: %2, %3") - .arg(x) - .arg(y) - .arg(this->getMovementPermissionText(collision, elevation))); + .arg(pos.x()) + .arg(pos.y()) + .arg(this->getMovementPermissionText(block.collision(), block.elevation()))); } else if (this->editMode == EditMode::Events) { this->ui->statusBar->showMessage(QString("X: %1, Y: %2, Scale = %3x") - .arg(x) - .arg(y) + .arg(pos.x()) + .arg(pos.y()) .arg(QString::number(zoomLevels[this->scaleIndex], 'g', 2))); } }