From 67e01aab85607b9e601185c7d62dff576af3bb43 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Fri, 18 Sep 2026 15:42:23 -0400 Subject: fix: close map OOM, admin traversal, transport safespot, room rekey, and legacy payout recovery --- internal/game/cmd_map.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'internal/game/cmd_map.go') diff --git a/internal/game/cmd_map.go b/internal/game/cmd_map.go index fc4ebf1..e84d1ce 100644 --- a/internal/game/cmd_map.go +++ b/internal/game/cmd_map.go @@ -2,14 +2,22 @@ package game import ( "thehouseoficarus/internal/net" + "thehouseoficarus/internal/player" ) func (g *Game) executeMap(sess *net.Session, args []string, rawInput string) { g.doMap(sess) } -func (g *Game) doMap(sess *net.Session) { - p := sess.Player +// maxMapDimension bounds the grid a player may request. buildFullMap +// allocates mapHeight x mapWidth cells, so an unbounded option value would let +// any authenticated player trigger a fatal (unrecoverable) out-of-memory +// allocation that takes the whole server down. The option parser accepts any +// int and the value persists in the account file, so the clamp must live here. +const maxMapDimension = 200 + +// mapDimensions returns the clamped map grid size requested by the player. +func mapDimensions(p *player.Player) (int, int) { mapWidth := p.OptionInt("map_width") mapHeight := p.OptionInt("map_height") if mapWidth < 5 { @@ -18,6 +26,18 @@ func (g *Game) doMap(sess *net.Session) { if mapHeight < 5 { mapHeight = 5 } + if mapWidth > maxMapDimension { + mapWidth = maxMapDimension + } + if mapHeight > maxMapDimension { + mapHeight = maxMapDimension + } + return mapWidth, mapHeight +} + +func (g *Game) doMap(sess *net.Session) { + p := sess.Player + mapWidth, mapHeight := mapDimensions(p) lines := buildFullMap(g, sess, p.RoomID, mapWidth, mapHeight, mapGlyphsForPlayer(p.OptionBool("unicode"))) -- cgit v1.2.3