diff --git a/src/management/marketing.c b/src/management/marketing.c index 7e3a4a16be..55cf24c521 100644 --- a/src/management/marketing.c +++ b/src/management/marketing.c @@ -155,6 +155,13 @@ void game_command_start_campaign(int* eax, int* ebx, int* ecx, int* edx, int* es int rideOrItem = (*edx >> 8) & 0xFF; int numWeeks = (*ebx >> 8) & 0xFF; + if (type < 0 || type >= countof(AdvertisingCampaignPricePerWeek)) + { + log_warning("Invalid game command, type = %d", type); + *ebx = MONEY32_UNDEFINED; + return; + } + RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_MARKETING * 4; if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN) { RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 3048; diff --git a/src/peep/staff.c b/src/peep/staff.c index 7ded0b1528..f1adf05318 100644 --- a/src/peep/staff.c +++ b/src/peep/staff.c @@ -293,7 +293,13 @@ void game_command_set_staff_order(int *eax, int *ebx, int *ecx, int *edx, int *e RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_WAGES * 4; uint8 order_id = *ebx >> 8; uint16 sprite_id = *edx; - if(*ebx & GAME_COMMAND_FLAG_APPLY){ + if (sprite_id >= MAX_SPRITES) + { + log_warning("Invalid game command, sprite_id = %u", sprite_id); + *ebx = MONEY32_UNDEFINED; + return; + } + if (*ebx & GAME_COMMAND_FLAG_APPLY) { rct_peep *peep = &g_sprite_list[sprite_id].peep; if(order_id & 0x80){ // change costume uint8 sprite_type = order_id & ~0x80; @@ -366,7 +372,19 @@ void game_command_fire_staff_member(int *eax, int *ebx, int *ecx, int *edx, int if(*ebx & GAME_COMMAND_FLAG_APPLY){ window_close_by_class(WC_FIRE_PROMPT); uint16 sprite_id = *edx; + if (sprite_id >= MAX_SPRITES) + { + log_warning("Invalid game command, sprite_id = %u", sprite_id); + *ebx = MONEY32_UNDEFINED; + return; + } rct_peep *peep = &g_sprite_list[sprite_id].peep; + if (peep->sprite_identifier != SPRITE_IDENTIFIER_PEEP || peep->type != PEEP_TYPE_STAFF) + { + log_warning("Invalid game command, peep->sprite_identifier = %u, peep->type = %u", peep->sprite_identifier, peep->type); + *ebx = MONEY32_UNDEFINED; + return; + } remove_peep_from_ride(peep); peep_sprite_remove(peep); } diff --git a/src/ride/ride.c b/src/ride/ride.c index 78da7a1230..2229b51c0c 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -2914,7 +2914,15 @@ static bool ride_does_vehicle_colour_exist(uint8 ride_sub_type, vehicle_colour * static int ride_get_unused_preset_vehicle_colour(uint8 ride_type, uint8 ride_sub_type) { + if (ride_sub_type >= 128) + { + return 0; + } rct_ride_type *rideEntry = GET_RIDE_ENTRY(ride_sub_type); + if (rideEntry == (rct_ride_type *)0xFFFFFFFF) + { + return 0; + } vehicle_colour_preset_list *presetList = rideEntry->vehicle_preset_list; if (presetList->count == 255) return 255; @@ -3588,6 +3596,12 @@ void game_command_set_ride_setting(int *eax, int *ebx, int *ecx, int *edx, int * uint8 ride_id = *edx & 0xFF; rct_ride* ride = GET_RIDE(ride_id); + if (ride->type == RIDE_TYPE_NULL) + { + log_warning("Invalid game command."); + *ebx = MONEY32_UNDEFINED; + return; + } uint8 flags = *ebx & 0xFF; uint8 new_value = (*ebx >> 8) & 0xFF; @@ -4606,6 +4620,11 @@ int ride_is_valid_for_test(int rideIndex, int goingToBeOpen, int isApplying) rct_xy_element trackElement, problematicTrackElement; ride = GET_RIDE(rideIndex); + if (ride->type == RIDE_TYPE_NULL) + { + log_warning("Invalid ride type for ride %u", rideIndex); + return 0; + } window_close_by_number(WC_RIDE_CONSTRUCTION, rideIndex); @@ -4864,6 +4883,12 @@ void game_command_set_ride_status(int *eax, int *ebx, int *ecx, int *edx, int *e RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS * 4; ride = GET_RIDE(rideIndex); + if (ride->type == RIDE_TYPE_NULL) + { + log_warning("Invalid game command for ride %u", rideIndex); + *ebx = MONEY32_UNDEFINED; + return; + } RCT2_GLOBAL(0x00F43484, uint32) = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8), uint32); switch (targetStatus) { @@ -4944,6 +4969,7 @@ void game_command_set_ride_name(int *eax, int *ebx, int *ecx, int *edx, int *esi if (nameChunkOffset < 0) nameChunkOffset = 2; nameChunkOffset *= 12; + nameChunkOffset = min(nameChunkOffset, countof(newName) - 12); RCT2_GLOBAL(newName + nameChunkOffset + 0, uint32) = *edx; RCT2_GLOBAL(newName + nameChunkOffset + 4, uint32) = *ebp; RCT2_GLOBAL(newName + nameChunkOffset + 8, uint32) = *edi; @@ -5162,6 +5188,10 @@ static int ride_get_random_colour_preset_index(uint8 ride_type) { const track_colour_preset_list *colourPresets; const track_colour *colours; + if (ride_type >= 128) + { + return 0; + } colourPresets = RCT2_ADDRESS(0x0097D934, track_colour_preset_list*)[ride_type]; @@ -5265,6 +5295,11 @@ money32 ride_create(int type, int subType, int flags, int *outRideIndex, int *ou foundRideEntry: rideEntryIndex = subType; rideIndex = ride_get_empty_slot(); + if (subType >= 128) + { + log_warning("Invalid request for ride type %u", subType); + return MONEY32_UNDEFINED; + } if (rideIndex == -1) { RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_TOO_MANY_RIDES; return MONEY32_UNDEFINED; @@ -5287,6 +5322,11 @@ foundRideEntry: ride = GET_RIDE(rideIndex); rideEntry = GET_RIDE_ENTRY(rideEntryIndex); + if (rideEntry == (rct_ride_type *)0xFFFFFFFF) + { + log_warning("Invalid request for ride %u", rideIndex); + return MONEY32_UNDEFINED; + } ride->type = type; ride->subtype = rideEntryIndex; ride_set_colour_preset(ride, *outRideColour & 0xFF); @@ -5596,7 +5636,13 @@ void game_command_demolish_ride(int *eax, int *ebx, int *ecx, int *edx, int *esi RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_X, uint16) = 0; RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_Y, uint16) = 0; RCT2_GLOBAL(RCT2_ADDRESS_COMMAND_MAP_Z, uint16) = 0; - rct_ride *ride = &g_ride_list[ride_id]; + rct_ride *ride = GET_RIDE(ride_id); + if (ride->type == RIDE_TYPE_NULL) + { + log_warning("Invalid game command for ride %u", ride_id); + *ebx = MONEY32_UNDEFINED; + return; + } int x = 0, y = 0, z = 0; if(ride->overall_view != (uint16)-1){ x = ((ride->overall_view & 0xFF) * 32) + 16; @@ -5724,25 +5770,61 @@ void game_command_set_ride_appearance(int *eax, int *ebx, int *ecx, int *edx, in uint8 type = *ebx >> 8; uint8 value = *edx >> 8; int index = *edi; - rct_ride *ride = &g_ride_list[ride_id]; + if (index < 0) { + log_warning("Invalid game command, index %d out of bounds", index); + *ebx = MONEY32_UNDEFINED; + return; + } + rct_ride *ride = GET_RIDE(ride_id); + if (ride->type == RIDE_TYPE_NULL) { + log_warning("Invalid game command, ride_id = %u", ride_id); + *ebx = MONEY32_UNDEFINED; + return; + } + *ebx = 0; switch(type){ case 0: + if (index >= countof(ride->track_colour_main)) { + log_warning("Invalid game command, index %d out of bounds", index); + *ebx = MONEY32_UNDEFINED; + break; + } ride->track_colour_main[index] = value; gfx_invalidate_screen(); break; case 1: + if (index >= countof(ride->track_colour_additional)) { + log_warning("Invalid game command, index %d out of bounds", index); + *ebx = MONEY32_UNDEFINED; + break; + } ride->track_colour_additional[index] = value; gfx_invalidate_screen(); break; case 2: + if (index >= countof(ride->vehicle_colours)) { + log_warning("Invalid game command, index %d out of bounds", index); + *ebx = MONEY32_UNDEFINED; + break; + } *((uint8*)(&ride->vehicle_colours[index])) = value; ride_update_vehicle_colours(ride_id); break; case 3: + if (index >= countof(ride->vehicle_colours)) { + log_warning("Invalid game command, index %d out of bounds", index); + *ebx = MONEY32_UNDEFINED; + break; + } *((uint8*)(&ride->vehicle_colours[index]) + 1) = value; ride_update_vehicle_colours(ride_id); break; case 4: + if (index >= countof(ride->track_colour_supports)) { + log_warning("Invalid game command, index %d out of bounds", index); + *ebx = MONEY32_UNDEFINED; + break; + } ride->track_colour_supports[index] = value; gfx_invalidate_screen(); break; @@ -5761,13 +5843,17 @@ void game_command_set_ride_appearance(int *eax, int *ebx, int *ecx, int *edx, in gfx_invalidate_screen(); break; case 7: + if (index >= countof(ride->vehicle_colours_extended)) { + log_warning("Invalid game command, index %d out of bounds", index); + *ebx = MONEY32_UNDEFINED; + break; + } ride->vehicle_colours_extended[index] = value; ride_update_vehicle_colours(ride_id); break; } window_invalidate_by_number(WC_RIDE, ride_id); } - *ebx = 0; } /** @@ -5780,21 +5866,28 @@ void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *es uint8 ride_number; money16 price; rct_ride *ride; - rct_ride_type *ride_type; + rct_ride_type *rideEntry; bool secondary_price; flags = *ebx; ride_number = (*edx & 0xFF); ride = GET_RIDE(ride_number); - ride_type = gRideTypeList[ride->subtype]; + rideEntry = GET_RIDE_ENTRY(ride->subtype); price = *edi; secondary_price = (*edx >> 8); + if (rideEntry == (rct_ride_type *)0xFFFFFFFF) + { + log_warning("Invalid game command for ride %u", ride_number); + *ebx = MONEY32_UNDEFINED; + return; + } + //eax //ebx flags //ecx ecx //edx ride_number - //ebp ride_type + //ebp rideEntry *ebx = 0; // for cost check - changing ride price does not cost anything @@ -5803,7 +5896,7 @@ void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *es if (!secondary_price) { shop_item = 0x1F; if (ride->type != RIDE_TYPE_TOILETS) { - shop_item = ride_type->shop_item; + shop_item = rideEntry->shop_item; if (shop_item == 0xFF) { ride->price = price; window_invalidate_by_class(WC_RIDE); @@ -5818,7 +5911,7 @@ void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *es } } else { - shop_item = ride_type->shop_item_secondary; + shop_item = rideEntry->shop_item_secondary; if (shop_item == 0xFF) { shop_item = RCT2_GLOBAL(0x0097D7CB + (ride->type * 4), uint8); if ((ride->lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO) == 0) { @@ -5835,12 +5928,12 @@ void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *es } } ride = GET_RIDE(0); - ride_type = gRideTypeList[ride->subtype]; + rideEntry = GET_RIDE_ENTRY(ride->subtype); uint8 count = 0; while (count < 0xFF) { if (ride->type != 0xFF) { if (ride->type != RIDE_TYPE_TOILETS || shop_item != 0x1F) { - if (ride_type->shop_item == shop_item) { + if (rideEntry->shop_item == shop_item) { ride->price = price; window_invalidate_by_number(WC_RIDE, count); } @@ -5850,8 +5943,8 @@ void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *es window_invalidate_by_number(WC_RIDE, count); } // If the shop item is the same or an on-ride photo - if (ride_type->shop_item_secondary == shop_item || - (ride_type->shop_item_secondary == 0xFF && + if (rideEntry->shop_item_secondary == shop_item || + (rideEntry->shop_item_secondary == 0xFF && (shop_item == 0x3 || shop_item == 0x20 || shop_item == 0x21 || shop_item == 0x22))) { ride->price_secondary = price; @@ -5860,7 +5953,7 @@ void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *es } count++; ride++; - ride_type = gRideTypeList[ride->subtype]; + rideEntry = GET_RIDE_ENTRY(ride->subtype); } } } @@ -6749,6 +6842,12 @@ void game_command_set_ride_vehicles(int *eax, int *ebx, int *ecx, int *edx, int value = (*edx >> 8) & 0xFF; ride = GET_RIDE(rideIndex); + if (ride->type == RIDE_TYPE_NULL) + { + log_warning("Invalid game command for ride %u", rideIndex); + *ebx = MONEY32_UNDEFINED; + return; + } RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS * 4; @@ -7090,6 +7189,11 @@ void game_command_place_ride_entrance_or_exit(int *eax, int *ebx, int *ecx, int money32 remove_ride_entrance_or_exit(sint16 x, sint16 y, uint8 rideIndex, uint8 station_num, uint8 flags){ rct_ride* ride = GET_RIDE(rideIndex); + if (ride->type == RIDE_TYPE_NULL) + { + log_warning("Invalide ride id %u for entrance/exit removal", rideIndex); + return MONEY32_UNDEFINED; + } if (!(flags & GAME_COMMAND_FLAG_GHOST)){ if (!(flags & GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED) && RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) != 0 && !gConfigCheat.build_in_pause_mode){ @@ -7110,6 +7214,11 @@ money32 remove_ride_entrance_or_exit(sint16 x, sint16 y, uint8 rideIndex, uint8 uint8 found = 0; rct_map_element* mapElement = map_get_first_element_at(x / 32, y / 32); + if (mapElement == NULL) + { + log_warning("Invalid coordinates for entrance/exit removal x = %d, y = %d", x, y); + return MONEY32_UNDEFINED; + } do{ if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_ENTRANCE) continue; diff --git a/src/ride/track.c b/src/ride/track.c index 978c71b91e..9a35bdd9c7 100644 --- a/src/ride/track.c +++ b/src/ride/track.c @@ -3309,6 +3309,14 @@ void game_command_place_track_design(int* eax, int* ebx, int* ecx, int* edx, int rideIndex = _edi & 0xFF; } + rct_ride* ride = GET_RIDE(rideIndex); + if (ride->type == RIDE_TYPE_NULL) + { + log_warning("Invalid game command for track placement, ride id = %d", rideIndex); + *ebx = MONEY32_UNDEFINED; + return; + } + money32 cost = 0; if (!(flags & GAME_COMMAND_FLAG_APPLY)){ RCT2_GLOBAL(0x00F44150, uint8) = 0; @@ -3365,7 +3373,6 @@ void game_command_place_track_design(int* eax, int* ebx, int* ecx, int* edx, int if (num_circuits == 0) num_circuits = 1; game_do_command(0, GAME_COMMAND_FLAG_APPLY | (num_circuits << 8), 0, rideIndex | (9 << 8), GAME_COMMAND_SET_RIDE_SETTING, 0, 0); - rct_ride* ride = GET_RIDE(rideIndex); ride->lifecycle_flags |= RIDE_LIFECYCLE_NOT_CUSTOM_DESIGN; @@ -4511,6 +4518,11 @@ money32 track_remove(uint8 type, uint8 sequence, sint16 originX, sint16 originY, uint8 found = 0; rct_map_element* mapElement = map_get_first_element_at(originX / 32, originY / 32); + if (mapElement == NULL) + { + log_warning("Invalid coordinates for track removal. x = %d, y = %d", originX, originY); + return MONEY32_UNDEFINED; + } do{ if (mapElement->base_height * 8 != originZ) continue; @@ -4798,6 +4810,12 @@ void game_command_set_brakes_speed(int *eax, int *ebx, int *ecx, int *edx, int * } mapElement = map_get_first_element_at(x >> 5, y >> 5); + if (mapElement == NULL) + { + log_warning("Invalid game command for setting brakes speed. x = %d, y = %d", x, y); + *ebx = MONEY32_UNDEFINED; + return; + } do { if (mapElement->base_height * 8 != z) continue; diff --git a/src/world/map.c b/src/world/map.c index 8962ed1033..d782c40465 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -645,15 +645,18 @@ int map_is_location_owned(int x, int y, int z) { rct_map_element *mapElement; + // This check is to avoid throwing lots of messages in logs. if (x < (256 * 32) && y < (256 * 32)) { mapElement = map_get_surface_element_at(x / 32, y / 32); - if (mapElement->properties.surface.ownership & OWNERSHIP_OWNED) - return 1; - - if (mapElement->properties.surface.ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED) { - z /= 8; - if (z < mapElement->base_height || z - 2 > mapElement->base_height) + if (mapElement != NULL) { + if (mapElement->properties.surface.ownership & OWNERSHIP_OWNED) return 1; + + if (mapElement->properties.surface.ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED) { + z /= 8; + if (z < mapElement->base_height || z - 2 > mapElement->base_height) + return 1; + } } } @@ -708,6 +711,12 @@ void game_command_remove_scenery(int* eax, int* ebx, int* ecx, int* edx, int* es money32 cost; rct_scenery_entry *entry = g_smallSceneryEntries[scenery_type]; + if (entry == (rct_scenery_entry *)0xFFFFFFFF) + { + log_warning("Invalid game command for scenery removal, scenery_type = %u", scenery_type); + *ebx = MONEY32_UNDEFINED; + return; + } cost = entry->small_scenery.removal_price * 10; RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_LANDSCAPING * 4; @@ -793,6 +802,12 @@ void game_command_remove_large_scenery(int* eax, int* ebx, int* ecx, int* edx, i bool element_found = false; rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); + if (map_element == NULL) + { + log_warning("Invalid game command for scenery removal, x = %d, y = %d", x, y); + *ebx = MONEY32_UNDEFINED; + return; + } do { if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_SCENERY_MULTIPLE) continue; @@ -2128,6 +2143,11 @@ static money32 smooth_land_tile(int direction, uint8 flags, int x, int y, int ta // Get height of tile rct_map_element *mapElement = map_get_surface_element_at(x >> 5, y >> 5); + if (mapElement == NULL) + { + log_warning("Invalid coordinates for land smoothing, x = %d, y = %d", x, y); + return MONEY32_UNDEFINED; + } int baseZ = map_get_corner_height(mapElement, direction); // Check if tile is same height as target tile @@ -2200,6 +2220,11 @@ money32 smooth_land(int flags, int centreX, int centreY, int mapLeft, int mapTop x = mapLeft; y = mapTop; mapElement = map_get_surface_element_at(x >> 5, y >> 5); + if (mapElement == NULL) + { + log_warning("Invalid coordinates for land smoothing, x = %d, y = %d", x, y); + return MONEY32_UNDEFINED; + } int slope = mapElement->properties.surface.slope & MAP_ELEMENT_SLOPE_MASK; if (slope != 0) { commandType = command == 0xFFFF ? GAME_COMMAND_RAISE_LAND : GAME_COMMAND_LOWER_LAND; @@ -3294,12 +3319,25 @@ void game_command_place_large_scenery(int* eax, int* ebx, int* ecx, int* edx, in return; } + if (entry_index >= 128) + { + log_warning("Invalid game command for scenery placement, entry_index = %u", entry_index); + *ebx = MONEY32_UNDEFINED; + return; + } + if (!sub_68B044()) { *ebx = MONEY32_UNDEFINED; return; } rct_scenery_entry* scenery_entry = RCT2_ADDRESS(RCT2_ADDRESS_LARGE_SCENERY_ENTRIES, rct_scenery_entry*)[entry_index]; + if (scenery_entry == (rct_scenery_entry *)0xFFFFFFFF) + { + log_warning("Invalid game command for scenery placement, entry_index = %u", entry_index); + *ebx = MONEY32_UNDEFINED; + return; + } if(scenery_entry->large_scenery.var_11 != 0xFF){ banner_id = create_new_banner(flags); @@ -4284,6 +4322,10 @@ bool map_element_is_underground(rct_map_element *mapElement) rct_map_element *map_get_large_scenery_segment(int x, int y, int z, int direction, int sequence) { rct_map_element *mapElement = map_get_first_element_at(x >> 5, y >> 5); + if (mapElement == NULL) + { + return NULL; + } do { if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_SCENERY_MULTIPLE) continue; @@ -4767,6 +4809,12 @@ void game_command_place_park_entrance(int* eax, int* ebx, int* ecx, int* edx, in void game_command_set_banner_name(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) { static char newName[128]; + if ((*ecx >= MAX_BANNERS) || (*ecx < 0)) + { + log_warning("Invalid game command for setting banner name, banner id = %d", *ecx); + *ebx = MONEY32_UNDEFINED; + return; + } rct_banner* banner = &gBanners[*ecx]; int nameChunkIndex = *eax & 0xFFFF; @@ -4776,6 +4824,7 @@ void game_command_set_banner_name(int* eax, int* ebx, int* ecx, int* edx, int* e if (nameChunkOffset < 0) nameChunkOffset = 2; nameChunkOffset *= 12; + nameChunkOffset = min(nameChunkOffset, countof(newName) - 12); RCT2_GLOBAL(newName + nameChunkOffset + 0, uint32) = *edx; RCT2_GLOBAL(newName + nameChunkOffset + 4, uint32) = *ebp; RCT2_GLOBAL(newName + nameChunkOffset + 8, uint32) = *edi; @@ -4811,6 +4860,12 @@ void game_command_set_banner_name(int* eax, int* ebx, int* ecx, int* edx, int* e void game_command_set_sign_name(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) { static char newName[128]; + if ((*ecx >= MAX_BANNERS) || (*ecx < 0)) + { + log_warning("Invalid game command for setting sign name, banner id = %d", *ecx); + *ebx = MONEY32_UNDEFINED; + return; + } rct_banner* banner = &gBanners[*ecx]; int x = banner->x << 5; int y = banner->y << 5; @@ -4822,6 +4877,7 @@ void game_command_set_sign_name(int* eax, int* ebx, int* ecx, int* edx, int* esi if (nameChunkOffset < 0) nameChunkOffset = 2; nameChunkOffset *= 12; + nameChunkOffset = min(nameChunkOffset, countof(newName) - 12); RCT2_GLOBAL(newName + nameChunkOffset + 0, uint32) = *edx; RCT2_GLOBAL(newName + nameChunkOffset + 4, uint32) = *ebp; RCT2_GLOBAL(newName + nameChunkOffset + 8, uint32) = *edi; @@ -4866,6 +4922,12 @@ void game_command_set_sign_name(int* eax, int* ebx, int* ecx, int* edx, int* esi } void game_command_set_banner_style(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) { + if ((*ecx >= MAX_BANNERS) || (*ecx < 0)) + { + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_INVALID_SELECTION_OF_OBJECTS; + *ebx = MONEY32_UNDEFINED; + return; + } rct_banner* banner = &gBanners[*ecx]; banner->colour = (uint8)*edx; diff --git a/src/world/park.c b/src/world/park.c index 6512d2a9a4..e17e053359 100644 --- a/src/world/park.c +++ b/src/world/park.c @@ -871,6 +871,7 @@ void game_command_set_park_name(int *eax, int *ebx, int *ecx, int *edx, int *esi if (nameChunkOffset < 0) nameChunkOffset = 2; nameChunkOffset *= 12; + nameChunkOffset = min(nameChunkOffset, countof(newName) - 12); RCT2_GLOBAL(newName + nameChunkOffset + 0, uint32) = *edx; RCT2_GLOBAL(newName + nameChunkOffset + 4, uint32) = *ebp; RCT2_GLOBAL(newName + nameChunkOffset + 8, uint32) = *edi;