Merge pull request #3160 from silverflyone/develop

Fix to read access violation in StockpileIterator::operator++
develop
Myk 2023-04-04 22:55:55 -07:00 committed by GitHub
commit bb5039d648
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 4 deletions

@ -39,6 +39,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- `hotkeys`: hotkey hints on menu popup will no longer get their last character cut off by the scrollbar - `hotkeys`: hotkey hints on menu popup will no longer get their last character cut off by the scrollbar
- ``launchdf``: launch Dwarf Fortress via the Steam client so Steam Workshop is functional - ``launchdf``: launch Dwarf Fortress via the Steam client so Steam Workshop is functional
- `blueprint`: interpret saplings, shrubs, and twigs as floors instead of walls - `blueprint`: interpret saplings, shrubs, and twigs as floors instead of walls
- `combine`: fix error processing stockpiles with boundaries that extend outside of the map
## Misc Improvements ## Misc Improvements
- `buildingplan`: items in the item selection dialog should now use the same item quality symbols as the base game - `buildingplan`: items in the item selection dialog should now use the same item quality symbols as the base game

@ -1645,19 +1645,25 @@ StockpileIterator& StockpileIterator::operator++() {
if (block) { if (block) {
// Check the next item in the current block. // Check the next item in the current block.
++current; ++current;
}
else if (stockpile->x2 < 0 || stockpile->y2 < 0 || stockpile->z < 0 || stockpile->x1 > world->map.x_count - 1 || stockpile->y1 > world->map.y_count - 1 || stockpile->z > world->map.z_count - 1) {
// if the stockpile bounds exist outside of valid map plane then no items can be in the stockpile
block = NULL;
item = NULL;
return *this;
} else { } else {
// Start with the top-left block covering the stockpile. // Start with the top-left block covering the stockpile.
block = Maps::getTileBlock(stockpile->x1, stockpile->y1, stockpile->z); block = Maps::getTileBlock(std::min(std::max(stockpile->x1, 0), world->map.x_count-1), std::min(std::max(stockpile->y1, 0), world->map.y_count-1), stockpile->z);
current = 0; current = 0;
} }
while (current >= block->items.size()) { while (current >= block->items.size()) {
// Out of items in this block; find the next block to search. // Out of items in this block; find the next block to search.
if (block->map_pos.x + 16 <= stockpile->x2) { if (block->map_pos.x + 16 <= std::min(stockpile->x2, world->map.x_count-1)) {
block = Maps::getTileBlock(block->map_pos.x + 16, block->map_pos.y, stockpile->z); block = Maps::getTileBlock(block->map_pos.x + 16, block->map_pos.y, stockpile->z);
current = 0; current = 0;
} else if (block->map_pos.y + 16 <= stockpile->y2) { } else if (block->map_pos.y + 16 <= std::min(stockpile->y2, world->map.y_count-1)) {
block = Maps::getTileBlock(stockpile->x1, block->map_pos.y + 16, stockpile->z); block = Maps::getTileBlock(std::max(stockpile->x1, 0), block->map_pos.y + 16, stockpile->z);
current = 0; current = 0;
} else { } else {
// All items in all blocks have been checked. // All items in all blocks have been checked.