aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2025-05-18 11:10:09 -0700
committerrtk0c <[email protected]>2025-05-18 11:10:09 -0700
commit838792fca41b9bccce260e9500d75549433bbe6a (patch)
treea6552fa2d9dbfeebc69f13d7cffca6d29b219c7c
parent3af71b8aa4976d2eb6ed9eb61e9e8ac5bd6d309a (diff)
Add bounds check to set_sand()HEADmaster
Previously, painting didn't do it (simulation did) so there were buffer overruns
-rw-r--r--src/sandbox.cpp31
-rw-r--r--src/sandbox.hpp6
-rw-r--r--src/ui.cpp2
3 files changed, 28 insertions, 11 deletions
diff --git a/src/sandbox.cpp b/src/sandbox.cpp
index 2c09d77..64bf1db 100644
--- a/src/sandbox.cpp
+++ b/src/sandbox.cpp
@@ -60,8 +60,8 @@ static void simulate_sand_tile(Sandbox& self, int x, int y) {
case Tile::Ti_Sand: {
const auto below = self.gs(x, y - 1);
if (below.so == Tile::Ti_Air) {
- self.set_sand(x, y, below);
- self.set_sand(x, y - 1, at0);
+ self.ss(x, y, below);
+ self.ss(x, y - 1, at0);
} else {
Pt loc1[]{ Pt(x - 1, y - 1), Pt(x + 1, y - 1) };
auto bound = 2;
@@ -70,8 +70,8 @@ static void simulate_sand_tile(Sandbox& self, int x, int y) {
// Try going to a side
auto at1 = self.gs(loc1[i].x, loc1[i].y);
if (at1.so == Tile::Ti_Air) {
- self.set_sand(x, y, at1);
- self.set_sand(loc1[i].x, loc1[i].y, at0);
+ self.ss(x, y, at1);
+ self.ss(loc1[i].x, loc1[i].y, at0);
}
which = (which + 1) % bound;
}
@@ -123,19 +123,32 @@ void Sandbox::simulate_step() {
++ncycle;
}
+#define BOUNDS_CHECK(x, y) if (x < 0 || x >= width || y < 0 || y >= height)
+
Tile& Sandbox::gs(int x, int y) {
- if (x < 0 || x >= width || y < 0 || y >= height)
+ BOUNDS_CHECK(x, y) {
return _wall_tile;
+ }
+
return tiles[y * width + x];
}
-void Sandbox::set_sand(int x, int y, Tile sand) {
+void Sandbox::ss(int x, int y, Tile sand) {
+ BOUNDS_CHECK(x, y) {
+ return;
+ }
+
+ // Update tile
auto& target = tiles[y * width + x];
target = sand;
- // Set update bit if the target is after cursor
- if (y < _y || x > _x)
- target.updated = true;
+ target.updated = true;
+ // Update visuals
bitmap[y * width + x] = sand.get_color();
+
+ mark_dirty(x, y);
+}
+
+void Sandbox::mark_dirty(int x, int y) {
if (dirty_writeto == Rect())
dirty_writeto = Rect(x, y, x, y);
else
diff --git a/src/sandbox.hpp b/src/sandbox.hpp
index 400f8ec..0ae8082 100644
--- a/src/sandbox.hpp
+++ b/src/sandbox.hpp
@@ -47,9 +47,13 @@ struct Sandbox {
void simulate_step();
+ // "Get Sand"
Tile& gs(int x, int y);
- void set_sand(int x, int y, Tile sand);
+ // "Set Sand"
+ void ss(int x, int y, Tile sand);
void shift_sand(int x, int y);
+ void mark_dirty(int x, int y); // UNCHECKED
+
// std::vector<uint32_t> to_bitmap() const;
};
diff --git a/src/ui.cpp b/src/ui.cpp
index 64a8a91..4337a3d 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -105,7 +105,7 @@ static void paint_sand(Sandbox& sb, const Tile& palette, Pt pt, BrushType type,
int x0 = pt.x - size / 2;
for (int y = y0; y < y0 + size; ++y) {
for (int x = x0; x < x0 + size; ++x) {
- sb.set_sand(x, y, palette);
+ sb.ss(x, y, palette);
}
}
} break;