From d639cb1a58b5ecbc8bc7893f7a08aaa8520323db Mon Sep 17 00:00:00 2001 From: Samuel Walladge Date: Tue, 27 Feb 2018 13:10:52 +1030 Subject: [PATCH] add map method to sanitize untrusted coords --- pyspades/player.py | 7 +++---- pyspades/vxl.pxd | 1 + pyspades/vxl.pyx | 20 ++++++++++++++++++++ pyspades/vxl_c.h | 2 +- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/pyspades/player.py b/pyspades/player.py index 9d158601d..917a15097 100644 --- a/pyspades/player.py +++ b/pyspades/player.py @@ -814,10 +814,9 @@ def drop_flag(self): if player is not self: continue position = self.world_object.position - x = int(position.x) - y = int(position.y) - z = max(0, int(position.z)) - z = self.protocol.map.get_z(x, y, z) + # convert to safe coords so the flag can't be dropped out of + # bounds or inside solid + x, y, z = self.protocol.map.get_safe_coords(position.x, position.y, position.z) flag.set(x, y, z) flag.player = None intel_drop.player_id = self.player_id diff --git a/pyspades/vxl.pxd b/pyspades/vxl.pxd index 9cc2cb5bb..91d888e5c 100644 --- a/pyspades/vxl.pxd +++ b/pyspades/vxl.pxd @@ -36,6 +36,7 @@ cdef class VXLData: cpdef tuple get_random_point(self, int x1, int y1, int x2, int y2) cpdef int get_z(self, int x, int y, int start = ?) cpdef int get_height(self, int x, int y) + cpdef tuple get_safe_coords(self, int x, int y, int z) cpdef bint has_neighbors(self, int x, int y, int z) cpdef bint is_surface(self, int x, int y, int z) cpdef list get_neighbors(self, int x, int y, int z) diff --git a/pyspades/vxl.pyx b/pyspades/vxl.pyx index def61afc7..12508a264 100644 --- a/pyspades/vxl.pyx +++ b/pyspades/vxl.pyx @@ -79,6 +79,7 @@ cdef class VXLData: if is_valid_position(x, y, z): set_point(x, y, z, self.map, 1, make_color(*color)) + # TODO: consider making this function raise error on invalid position cpdef get_solid(self, int x, int y, int z): if not is_valid_position(x, y, z): return None @@ -102,6 +103,25 @@ cdef class VXLData: return z + 1 return 0 + cpdef tuple get_safe_coords(self, int x, int y, int z): + ''' + given (x, y, z) coords, return the closest set of coords on the map + that is: + - within the bounds of the map + - not inside a solid + ''' + + # pull x and y to within bounds + x = min(max(0, x), 511) + y = min(max(0, y), 511) + + # make sure z is within bounds, + # and if solid, move upwards to first non-solid space + z = min(max(0, z), 63) + z = self.get_z(x, y, start=z) + + return (x, y, z) + cpdef tuple get_random_point(self, int x1, int y1, int x2, int y2): cdef int x, y get_random_point(x1, y1, x2, y2, self.map, random.random(), diff --git a/pyspades/vxl_c.h b/pyspades/vxl_c.h index 7247328c0..194b6a8e8 100644 --- a/pyspades/vxl_c.h +++ b/pyspades/vxl_c.h @@ -104,4 +104,4 @@ void inline set_column_color(int x, int y, int z_start, int z_end, } } -#endif /* VXL_C_H */ \ No newline at end of file +#endif /* VXL_C_H */