From 9a981ef68f3c0bb19347f4975a3249c38e4012b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 1 Nov 2015 18:44:16 +0100 Subject: [PATCH] Fix variable not being shifted When decompiled, at 0x6AA8ED, there's `shr edi,0x4`, which is not reflected in sources. The `type` without that shift could easily become a value large enough to point to memory beyond object entries and modify those values. In my case, it was modifying `RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS` from 2122 to 2123 (by setting lowest bit), which luckily, is used later in `setup_in_use_selection_flags`. For this reason, I believe it could be a major source of other problems, possibly also recent `MAP_ANIMATION` ones, although I haven't checked. I also put an assert in place to validate type against max available count. --- src/windows/editor_object_selection.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index 388af33f45..bd3b37fdd1 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -578,6 +578,8 @@ static void setup_in_use_selection_flags(){ break; case MAP_ELEMENT_TYPE_PATH: type = iter.element->properties.path.type; + type >>= 4; + assert(type < object_entry_group_counts[OBJECT_TYPE_PATHS]); RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_PATHS][type] |= (1 << 0); path_additions = iter.element->properties.path.additions & 0xF; @@ -588,6 +590,7 @@ static void setup_in_use_selection_flags(){ break; case MAP_ELEMENT_TYPE_SCENERY: type = iter.element->properties.scenery.type; + assert(type < object_entry_group_counts[OBJECT_TYPE_SMALL_SCENERY]); RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_SMALL_SCENERY][type] |= (1 << 0); break; case MAP_ELEMENT_TYPE_ENTRANCE: @@ -597,19 +600,23 @@ static void setup_in_use_selection_flags(){ RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_PARK_ENTRANCE][0] |= (1 << 0); type = iter.element->properties.entrance.path_type; + assert(type < object_entry_group_counts[OBJECT_TYPE_PATHS]); RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_PATHS][type] |= (1 << 0); break; case MAP_ELEMENT_TYPE_FENCE: type = iter.element->properties.fence.type; + assert(type < object_entry_group_counts[OBJECT_TYPE_WALLS]); RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_WALLS][type] |= (1 << 0); break; case MAP_ELEMENT_TYPE_SCENERY_MULTIPLE: type = iter.element->properties.scenerymultiple.type & 0x3FF; + assert(type < object_entry_group_counts[OBJECT_TYPE_LARGE_SCENERY]); RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_LARGE_SCENERY][type] |= (1 << 0); break; case MAP_ELEMENT_TYPE_BANNER: banner = &gBanners[iter.element->properties.banner.index]; type = banner->type; + assert(type < object_entry_group_counts[OBJECT_TYPE_BANNERS]); RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_BANNERS][type] |= (1 << 0); break; }