This repository has been archived on 2025-03-20. You can view files and clone it, but cannot push or open issues or pull requests.
The-Powder-Toy/src/simulation
Tamás Bálint Misius b4462273b0
Fix a very elusive PHOT reflection crash
get_normal_interp is given a PHOT and scans a line section starting from the PHOT, extended in the direction of its velocity, to determine the surface normal of the surface that is reflecting the PHOT. It uses is_boundary to detect "boundaries" on this line section, defined as one "blocking" cell with at least one "non-blocking" non-diagonal neighbour. It never actually makes sure the position it passes to is_boundary is within the simulation area, so I assume is_boundary is expected to handle this correctly.

Plot twist: it does not. It delegates checking whether a cell is "blocking" (defined as something PHOT would normally fail to move into as per eval_move, but GLAS and BLGA are handled specially) to is_blocking. is_blocking returns true for cells beyond the simulation area (as eval_move returns "no move" for such cells). Once is_boundary sees that the cell it's been given is blocking, it then proceeds to check whether any of its non-diagonal neighbours might be non-blocking. In most cases, non-diagonal neighbours of an out-of-bounds cell are also out of bounds and are thus blocking, but if the cell is_boundary is given is in the innermost layer of out-of-bounds cells, just beyond the simulation area, then it has a neighbour that is in bounds, and that one may not block PHOT. The takeaway is that out of bounds cells can indeed be boundaries, as far as is_boundary is concerned.

This is a problem because get_normal_interp's line section can easily reach beyond the simulation area if the PHOT's velocity is high enough, and if it finds a boundary along this line section, it immediately stops looking and passes its position to photoelectric_effect, which then uses this potentially out-of-bounds position to index pmap. A position with y = -1 causes photoelectric_effect to read from the last few slots of parts data that it then interprets as pmap entries, which then may direct it to particles to spark that are beyond parts. This eventually crashes.

This commit doesn't fix is_boundary's definition of boundaries, but it stops get_normal_interp looking at cells beyond the simulation area.

The crash is difficult to reproduce because there have to be many particles in the simulation for the very last slots of parts to be in use, and for them to point to memory that isn't accessible. PHOT also has to survive a try_move beyond the simulation area first (otherwise the reflection code isn't even run), which requires it to start from EHOLE. I have no idea why this is so. Reproduce the out of bounds read in photoelectric_effect with

	break Simulation.cpp:2934 if nx < 0

in gdb and executing the following Lua code:

	sim.clearSim()
	tpt.set_wallmap(55, 44, 12)
	local i = sim.partCreate(-1, 223, 178, 31)
	sim.partProperty(i, "vx", -300)
	sim.partProperty(i, "vy", 0)
	sim.framerender(1)
2022-10-02 22:57:36 +02:00
..
elements Make stickman movement strength independent of gravity (#857) 2022-09-25 14:49:43 +02:00
simtools Add AMBP and AMBM tools (#778) 2021-07-29 17:50:24 +02:00
Air.cpp Add custom gravity mode and replace hardcoded gravity interactions (#820) 2022-07-31 08:19:16 +02:00
Air.h ensure air doesn't "leak" out of TTAN containers when loading stamps and saves 2017-08-02 23:49:51 -04:00
BuiltinGOL.h Custom GOL (#731) 2020-10-08 20:23:59 +02:00
CoordStack.h Fix clang 8 compile warnings 2019-10-04 00:21:10 -04:00
Element.cpp Custom GOL (#731) 2020-10-08 20:23:59 +02:00
Element.h Mesonification 2020-12-14 20:16:52 +01:00
ElementClasses.cpp Ditch element and tool classes 2020-01-09 19:22:11 +01:00
ElementClasses.h Ditch element and tool classes 2020-01-09 19:22:11 +01:00
ElementCommon.h Mesonification 2020-12-14 20:16:52 +01:00
ElementDefs.h Fix PMAPBITS compile-time sanity check 2020-01-24 22:25:15 +01:00
ElementGraphics.h redo spark graphics, add spark render setting 2014-08-11 21:56:40 -04:00
ElementNumbers.template.h Mesonification 2020-12-14 20:16:52 +01:00
GOLString.cpp Fix render failing to compile with GCC 11 2021-12-07 16:44:48 +01:00
GOLString.h Add a few more Lua functions 2021-08-27 23:57:55 -04:00
Gravity.cpp Fix a metric ton of MSVC warnings 2021-02-15 21:24:44 +01:00
Gravity.h Mesonification 2020-12-14 20:16:52 +01:00
MenuSection.h Move TPT's icons to the (real) Private Use Area of the unicode 2018-05-01 07:03:48 +03:00
meson.build Optimise undo history memory usage 2021-08-04 17:19:15 +02:00
Particle.cpp Alias dcolor, pavg0, pavg1 to dcolour, tmp3, tmp4 2022-08-08 08:55:32 +02:00
Particle.h Alias dcolor, pavg0, pavg1 to dcolour, tmp3, tmp4 2022-08-08 08:55:32 +02:00
Sample.h Flatten include trees 2019-04-20 15:36:11 +02:00
SaveRenderer.cpp Use std::vector<char> consistently for file operations 2022-09-08 06:45:25 +02:00
SaveRenderer.h Prevent SaveRenderer from calling into Lua 2022-02-23 22:22:10 +01:00
Sign.cpp Split Simulation::IsValidElement into IsElement and IsElementOrNone 2021-04-11 23:20:33 -04:00
Sign.h Mesonification 2020-12-14 20:16:52 +01:00
SimTool.cpp Upgrade to C++17 (#819) 2021-12-13 14:41:02 +01:00
SimTool.h Ditch element and tool classes 2020-01-09 19:22:11 +01:00
Simulation.cpp Fix a very elusive PHOT reflection crash 2022-10-02 22:57:36 +02:00
Simulation.h Add custom gravity mode and replace hardcoded gravity interactions (#820) 2022-07-31 08:19:16 +02:00
SimulationData.cpp Custom GOL (#731) 2020-10-08 20:23:59 +02:00
SimulationData.h Mesonification 2020-12-14 20:16:52 +01:00
Snapshot.h Optimise undo history memory usage 2021-08-04 17:19:15 +02:00
SnapshotDelta.cpp Upgrade to C++17 (#819) 2021-12-13 14:41:02 +01:00
SnapshotDelta.h Optimise undo history memory usage 2021-08-04 17:19:15 +02:00
Stickman.h fix STKM + fan wall 2018-03-21 23:58:27 -04:00
StorageClasses.h Flatten include trees 2019-04-20 15:36:11 +02:00
StructProperty.h Alias dcolor, pavg0, pavg1 to dcolour, tmp3, tmp4 2022-08-08 08:55:32 +02:00
ToolClasses.cpp Ditch element and tool classes 2020-01-09 19:22:11 +01:00
ToolClasses.h Ditch element and tool classes 2020-01-09 19:22:11 +01:00
ToolCommon.h Mesonification 2020-12-14 20:16:52 +01:00
ToolNumbers.template.h Mesonification 2020-12-14 20:16:52 +01:00
WallType.h Switch from std::string to String/ByteString in most of the code 2018-04-30 21:13:24 +03:00