Page 1 of 1

I just accidentally found a literal zip bomb for the ram in love

Posted: Sat Sep 23, 2023 1:35 am
by alejandroalzate
Hey guys with little boilerplate i'll go directly to the "Thing",
so i trying to develop a game and one of the features is video on the level's background, i was implementing the logic of pause menu (You can roast me btw):

Code: Select all

local function advanceTime(dt)
	if type("mediaContent") then
		local success, res = pcall(mediaContent.tell, mediaContent)
		if success then
			elapsedTime = res or 0
		else
			print(res)
		end
		--What i added, that caused the mayhem
		if type(menu) == "table" then
			if menu.show then
				waveSource:pause()
				mediaContent:pause()
			else
				mediaContent:play()
				waveSource:play()
			end
		end
	end
end
The supposed logic goal was that whenever the pause menu was on screen well is supposed to be a pause menu right? so we pause the video and resume after, my oversight was that once you unpaused, the thing will just spam the hell outta

Code: Select all

play()
, and i kid you not it just needed 3 seconds to fill my entire ram (8gb 7.9 usable - 2gb used by the system), apparently when called repeadtedly the play() method generates a lot of garbage i do not treat it as a bug since i'm supposed to call it once. but i thought that was worth the share of that oversight of mine.

Also the fix was dirty cheap for those wondering (roast allowed again):

Code: Select all

local function advanceTime(dt)
	if type("mediaContent") then
		local success, res = pcall(mediaContent.tell, mediaContent)
		if success then
			elapsedTime = res or 0
		else
			print(res)
		end
		if type(menu) == "table" then
			if menu.show then
				waveSource:pause()
				mediaContent:pause()
			else
				if mediaContent:tell() > 0 and not mediaContent:isPlaying() then
					mediaContent:play()
					waveSource:play()
				end
			end
		end
	end
end
But i'm also considering adding the check when paused as well just to play it safe

Re: I just accidentally found a literal zip bomb for the ram in love

Posted: Sat Sep 23, 2023 2:21 am
by MrFariator
While it's surprising that your example creates so much garbage, it's not also not particularly special, now is it? There are many ways to fill up RAM (excessive table creation, loading a bunch of assets into memory), force heavy CPU loads (just modifying love.run slightly could do), or cause excessive I/O operations (writing/deleting a bunch of files with love.filesystem), purposefully or otherwise, that in theory the set of LÖVE API functions that don't cause issues if used inappropriately is probably much smaller than the inverse.

At the end of the day, whenever you download something off the internet you kind of have to trust that the thing you grabbed isn't malicious.

Re: I just accidentally found a literal zip bomb for the ram in love

Posted: Sat Sep 23, 2023 4:41 am
by zorg
Technically, calling play on audio Sources while they are already playing should not do anything, so i'm really suprised if that would actually be the issue here and not something else you're also doing that you didn't share (e.g. calling :clone on one of the sources repeatedly; that *might* fill up memory if this happens tons of times every time update is called.)
Not sure about videos if that's what mediaContent is.

Re: I just accidentally found a literal zip bomb for the ram in love

Posted: Sat Sep 23, 2023 2:51 pm
by slime
There's at least one third party audio source wrapper library (SLAM) which overwrites Source:play to create a new Source each time it's called. If you're using that it'd cause huge memory increases when you call Source:play every frame.

Otherwise zorg is correct.