Browse Source

Add extra validation checks for map coordinates (#7526)

* Add extra validation checks for map coordinates
* Adds some extra validation checks for map coordinates when parsed in YAML.
Aleos 2 years ago
parent
commit
503b57dbef
4 changed files with 65 additions and 9 deletions
  1. 2 2
      src/common/mmo.hpp
  2. 34 2
      src/map/battleground.cpp
  3. 1 1
      src/map/battleground.hpp
  4. 28 4
      src/map/instance.cpp

+ 2 - 2
src/common/mmo.hpp

@@ -353,8 +353,8 @@ enum equip_pos : uint32 {
 };
 
 struct point {
-	unsigned short map;
-	short x,y;
+	uint16 map;
+	uint16 x,y;
 };
 
 struct startitem {

+ 34 - 2
src/map/battleground.cpp

@@ -298,13 +298,45 @@ uint64 BattlegroundDatabase::parseBodyNode(const ryml::NodeRef& node) {
 					}
 
 					if (this->nodeExists(team[team_name], "RespawnX")) {
-						if (!this->asInt16(team[team_name], "RespawnX", team_ptr->warp_x))
+						uint16 warp_x;
+
+						if (!this->asUInt16(team[team_name], "RespawnX", warp_x))
+							return 0;
+
+						if (warp_x == 0) {
+							this->invalidWarning(node["RespawnX"], "RespawnX has to be greater than zero.\n");
 							return 0;
+						}
+
+						map_data *md = map_getmapdata(map_mapindex2mapid(map_entry.mapindex));
+
+						if (warp_x >= md->xs) {
+							this->invalidWarning(node["RespawnX"], "RespawnX has to be smaller than %hu.\n", md->xs);
+							return 0;
+						}
+
+						team_ptr->warp_x = warp_x;
 					}
 
 					if (this->nodeExists(team[team_name], "RespawnY")) {
-						if (!this->asInt16(team[team_name], "RespawnY", team_ptr->warp_y))
+						uint16 warp_y;
+
+						if (!this->asUInt16(team[team_name], "RespawnY", warp_y))
+							return 0;
+
+						if (warp_y == 0) {
+							this->invalidWarning(node["RespawnY"], "RespawnY has to be greater than zero.\n");
 							return 0;
+						}
+
+						map_data *md = map_getmapdata(map_mapindex2mapid(map_entry.mapindex));
+
+						if (warp_y >= md->ys) {
+							this->invalidWarning(node["RespawnY"], "RespawnY has to be smaller than %hu.\n", md->ys);
+							return 0;
+						}
+
+						team_ptr->warp_y = warp_y;
 					}
 
 					if (this->nodeExists(team[team_name], "DeathEvent")) {

+ 1 - 1
src/map/battleground.hpp

@@ -31,7 +31,7 @@ struct s_battleground_data {
 };
 
 struct s_battleground_team {
-	int16 warp_x, warp_y; ///< Team respawn coordinates
+	uint16 warp_x, warp_y; ///< Team respawn coordinates
 	std::string quit_event, ///< Team NPC Event to call on log out events
 		death_event, ///< Team NPC Event to call on death events
 		active_event, ///< Team NPC Event to call on players joining an active battleground

+ 28 - 4
src/map/instance.cpp

@@ -178,20 +178,44 @@ uint64 InstanceDatabase::parseBodyNode(const ryml::NodeRef& node) {
 		}
 
 		if (this->nodeExists(enterNode, "X")) {
-			int16 x;
+			uint16 x;
 
-			if (!this->asInt16(enterNode, "X", x))
+			if (!this->asUInt16(enterNode, "X", x))
 				return 0;
 
+			if (x == 0) {
+				this->invalidWarning(node["X"], "X has to be greater than zero.\n");
+				return 0;
+			}
+
+			map_data *md = map_getmapdata(instance->enter.map);
+
+			if (x >= md->xs) {
+				this->invalidWarning(node["X"], "X has to be smaller than %hu.\n", md->xs);
+				return 0;
+			}
+
 			instance->enter.x = x;
 		}
 
 		if (this->nodeExists(enterNode, "Y")) {
-			int16 y;
+			uint16 y;
 
-			if (!this->asInt16(enterNode, "Y", y))
+			if (!this->asUInt16(enterNode, "Y", y))
 				return 0;
 
+			if (y == 0) {
+				this->invalidWarning(node["Y"], "Y has to be greater than zero.\n");
+				return 0;
+			}
+
+			map_data *md = map_getmapdata(instance->enter.map);
+
+			if (y >= md->ys) {
+				this->invalidWarning(node["Y"], "Y has to be smaller than %hu.\n", md->ys);
+				return 0;
+			}
+
 			instance->enter.y = y;
 		}
 	}