Compare commits

...

5 Commits

Author SHA1 Message Date
Lars Mueller 8d6295bad9 Improve Readme 2022-07-04 16:45:34 +02:00
Lars Mueller 8cf8a755ae Get rid of broken name hack 2022-06-30 22:21:58 +02:00
Lars Mueller 2c92b0b992 Readme: Document load order hack 2022-06-29 16:52:29 +02:00
Lars Mueller ffe37eb64c Add math.random strictness 2022-06-29 00:28:22 +02:00
Lars Mueller 7eae1db5a5 Remove defunct code 2022-06-28 23:34:47 +02:00
3 changed files with 62 additions and 11 deletions

View File

@ -18,6 +18,14 @@ Particularly useful when writing new mods that don't target older Minetest versi
Potentially partially redundant with the `deprecated_lua_api_handling` setting.
## License
## Usage
Written by Lars Müller and licensed under the MIT license.
Install & enable `strictest`, then **make sure to optionally depend on it** in `mod.conf`.
Note that runtime strictness always comes at a cost. Running `strictest` on production servers under heavy load is thus not advisable.
---
Links: [GitHub](https://github.com/appgurueu/strictest), [ContentDB](https://content.minetest.net/packages/LMD/strictest/), [Minetest Forums](https://forum.minetest.net/viewtopic.php?t=28327)
License: Written by Lars Müller and licensed under the MIT license.

58
lua.lua
View File

@ -18,14 +18,9 @@ function str_mt.__index(_, key)
return func
end
-- Completely disable string-to-number coercion
-- Disable string-to-number coercion as much as possible
local arithmetic_ops = {"add", "sub", "mul", "div", "mod", "pow", "unm"}
for _, op in pairs(arithmetic_ops) do
str_mt["__" .. op] = function()
action"attempt to perform arithmetic on a string value"
end
end
-- Setting the metamethods unfortunately doesn't work - Lua ignores them
-- Override string methods to reject anything that isn't a string
for name, func in pairs(string) do
@ -64,3 +59,52 @@ for name, func in pairs(math) do
end
end
end
-- `math.random` strictness
-- Signed 32-bit int check
local function int32(num)
if num ~= num or math.abs(num) == math.huge then
action"expected 32-bit signed int, got nan or inf"
elseif num % 1 ~= 0 then
action"expected 32-bit signed int, got number with fractional part"
elseif num >= 2^31 then
action"expected 32-bit signed int, got too large number"
elseif num < -2^31 then
action"expected 32-bit signed int, got too small number"
end
end
-- PUC Lua uses 32-bit ints internally for math.random calls with intervals:
--[[
For one argument:
int u = luaL_checkint(L, 1);
luaL_argcheck(L, 1<=u, 1, "interval is empty");
lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */
For two arguments:
int l = luaL_checkint(L, 1);
int u = luaL_checkint(L, 2);
luaL_argcheck(L, l<=u, 2, "interval is empty");
lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
]]
local math_random = math.random
function math.random(...)
local n = select("#", ...)
if n == 0 then
return math_random()
elseif n == 1 then
local a = ...
int32(a)
return math_random(a)
elseif n == 2 then
local a, b = ...
int32(a); int32(b) -- limits must be inside int32 bounds
int32(b - a + 1) -- range may not overflow
return math_random(a, b)
else
action"expected at most 2 arguments in call to math.random"
end
end

View File

@ -1,4 +1,3 @@
# HACK use a double underscore to load before "all" other mods (reverse alphabetical order)
name = __strictest
name = strictest
title = Runtime Strictness
description = Disallows questionable usage of the Lua API & Lua itself to help catch errors