mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-10-30 23:15:32 +01:00 
			
		
		
		
	Deprecate function support in core.[de]serialize
				
					
				
			This commit is contained in:
		| @@ -14,11 +14,6 @@ local function basic_dump(o) | ||||
| 		return tostring(o) | ||||
| 	elseif tp == "nil" then | ||||
| 		return "nil" | ||||
| 	-- Uncomment for full function dumping support. | ||||
| 	-- Not currently enabled because bytecode isn't very human-readable and | ||||
| 	-- dump's output is intended for humans. | ||||
| 	--elseif tp == "function" then | ||||
| 	--	return string.format("loadstring(%q)", string.dump(o)) | ||||
| 	elseif tp == "userdata" then | ||||
| 		return tostring(o) | ||||
| 	else | ||||
|   | ||||
| @@ -190,7 +190,33 @@ local function serialize(value, write) | ||||
| 	dump(value) | ||||
| end | ||||
|  | ||||
| -- Whether `value` recursively contains a function | ||||
| local function contains_function(value) | ||||
| 	local seen = {} | ||||
| 	local function check(val) | ||||
| 		if type(val) == "function" then | ||||
| 			return true | ||||
| 		end | ||||
| 		if type(val) == "table" then | ||||
| 			if seen[val] then | ||||
| 				return false | ||||
| 			end | ||||
| 			seen[val] = true | ||||
| 			for k, v in pairs(val) do | ||||
| 				if check(k) or check(v) then | ||||
| 					return true | ||||
| 				end | ||||
| 			end | ||||
| 		end | ||||
| 		return false | ||||
| 	end | ||||
| 	return check(value) | ||||
| end | ||||
|  | ||||
| function core.serialize(value) | ||||
| 	if contains_function(value) then | ||||
| 		core.log("deprecated", "Support for dumping functions in `core.serialize` is deprecated.") | ||||
| 	end | ||||
| 	local rope = {} | ||||
| 	serialize(value, function(text) | ||||
| 		 -- Faster than table.insert(rope, text) on PUC Lua 5.1 | ||||
|   | ||||
| @@ -93,21 +93,49 @@ describe("serialize", function() | ||||
| 		assert_preserves(test_in) | ||||
| 	end) | ||||
|  | ||||
| 	it("strips functions in safe mode", function() | ||||
| 		local test_in = { | ||||
| 			func = function(a, b) | ||||
| 				error("test") | ||||
| 			end, | ||||
| 			foo = "bar" | ||||
| 		} | ||||
| 		setfenv(test_in.func, _G) | ||||
| 	describe("safe mode", function() | ||||
| 		setup(function() | ||||
| 			assert(not core.log) | ||||
| 			-- logging a deprecation warning will be attempted | ||||
| 			function core.log() end | ||||
| 		end) | ||||
| 		teardown(function() | ||||
| 			core.log = nil | ||||
| 		end) | ||||
| 		it("functions are stripped", function() | ||||
| 			local test_in = { | ||||
| 				func = function(a, b) | ||||
| 					error("test") | ||||
| 				end, | ||||
| 				foo = "bar" | ||||
| 			} | ||||
| 			setfenv(test_in.func, _G) | ||||
|  | ||||
| 		local str = core.serialize(test_in) | ||||
| 		assert.not_nil(str:find("loadstring")) | ||||
| 			local str = core.serialize(test_in) | ||||
| 			assert.not_nil(str:find("loadstring")) | ||||
|  | ||||
| 		local test_out = core.deserialize(str, true) | ||||
| 		assert.is_nil(test_out.func) | ||||
| 		assert.equals(test_out.foo, "bar") | ||||
| 			local test_out = core.deserialize(str, true) | ||||
| 			assert.is_nil(test_out.func) | ||||
| 			assert.equals(test_out.foo, "bar") | ||||
| 		end) | ||||
| 	end) | ||||
|  | ||||
| 	describe("deprecation warnings", function() | ||||
| 		before_each(function() | ||||
| 			assert(not core.log) | ||||
| 			core.log = spy.new(function(level) | ||||
| 				assert(level == "deprecated") | ||||
| 			end) | ||||
| 		end) | ||||
| 		after_each(function() | ||||
| 			core.log = nil | ||||
| 		end) | ||||
| 		it("dumping functions", function() | ||||
| 			local t = {f = function() end, g = function() end} | ||||
| 			t.t = t | ||||
| 			core.serialize(t) | ||||
| 			assert.spy(core.log).was.called(1) -- should have been called exactly *once* | ||||
| 		end) | ||||
| 	end) | ||||
|  | ||||
| 	it("vectors work", function() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user