LuaBlock: Major changes in mod storage usage

Data associated to a LuaBlock is redundantly stored in both its metadata
and in the mod storage so that it is not possible to hack a LuaBlock by
changing its metadata or copying it using WorldEdit. This commit changes
how it is done:
* Store full code instead of storing MD5 checksum, which avoids bug
caused by serializing non-ASCII strings using minetest.serialize,
* Also store owner,
* Use `minetest.hash_node_position` instead of deprecated vector_extras
set_data_to_pos etc,
* Remove mod storage data associated with the LuaBlock when destroying
it,
* Create helper functions for manipulating the mod storage in
moremesecons_utils, I will soon update other parts of MoreMesecons as well to use them.

This commit breaks backwards compatibility: previously created LuaBlocks
will have to be reset by opening the formspec and pressing the `Submit`
button.

This commit also fixes an unrelated bug: code in the formspec was not
correctly escaped using minetest.formspec_escape.
This commit is contained in:
upsilon 2020-04-09 16:13:51 +02:00
parent 2b2faeca02
commit 7cf99da1a5
No known key found for this signature in database
GPG Key ID: A80DAE1F266E1C3C
12 changed files with 50 additions and 652 deletions

@ -1,20 +1,21 @@
local md5 = dofile(minetest.get_modpath(minetest.get_current_modname()).."/md5_lua/md5.lua")
local storage = minetest.get_mod_storage()
local hash_table = minetest.deserialize(storage:get_string("hash_table")) or {}
local pos_data = moremesecons.get_storage_data(storage, "pos_data")
local function set_md5(pos, code)
vector.set_data_to_pos(hash_table, pos.z,pos.y,pos.x, md5.sum(code))
storage:set_string("hash_table", minetest.serialize(hash_table))
local function set_data(pos, code, owner)
local data = {
code = code,
owner = owner
}
moremesecons.set_data_to_pos(pos_data, pos, data)
end
local function check_md5(pos, code)
local stored_sum = vector.get_data_from_pos(hash_table, pos.z,pos.y,pos.x)
if not stored_sum then
-- Legacy
set_md5(pos, code)
return true
local function check_data(pos, code, owner)
local stored_data = moremesecons.get_data_from_pos(pos_data, pos)
if not stored_data then
return false
end
if md5.sum(code) ~= stored_sum then
if code ~= stored_data.code
or owner ~= stored_data.owner then
return false
end
return true
@ -22,11 +23,11 @@ end
local function make_formspec(meta, pos)
local code = meta:get_string("code")
local code = minetest.formspec_escape(meta:get_string("code"))
local errmsg = minetest.formspec_escape(meta:get_string("errmsg"))
meta:set_string("formspec",
"size[10,8;]" ..
"textarea[0.5,0.5;10,7;code;Code;"..code.."]" ..
"textarea[0.5,0.5;9.5,7;code;Code;"..code.."]" ..
"label[0.1,7;"..errmsg.."]" ..
"button_exit[4,7.5;2,1;submit;Submit]")
end
@ -97,22 +98,26 @@ minetest.register_node("moremesecons_luablock:luablock", {
end
meta:set_string("code", fields.code)
set_md5(pos, fields.code)
set_data(pos, fields.code, name)
make_formspec(meta, pos)
end,
can_dig = function(pos, player)
local meta = minetest.get_meta(pos)
return meta:get_string("owner") == player:get_player_name()
end,
on_destruct = function(pos)
moremesecons.remove_data_from_pos(pos_data, pos)
end,
mesecons = {effector = {
action_on = function(npos, node)
local meta = minetest.get_meta(npos)
local code = meta:get_string("code")
local owner = meta:get_string("owner")
if code == "" then
return
end
if not check_md5(npos, code) then
minetest.log("warning", "[moremesecons_luablock] Code of LuaBlock at pos "..minetest.pos_to_string(npos).." does not match with its md5 checksum!")
if not check_data(npos, code, owner) then
minetest.log("warning", "[moremesecons_luablock] Metadata of LuaBlock at pos "..minetest.pos_to_string(npos).." does not match its mod storage data!")
return
end
-- We do absolutely no check there.
@ -127,7 +132,10 @@ minetest.register_node("moremesecons_luablock:luablock", {
return
end
-- Set the "pos" global
local old_pos = pos -- In case there's already an existing "pos" global
local old_pos
if minetest.global_exists("pos") then
old_pos = pos -- In case there's already an existing "pos" global
end
pos = table.copy(npos)
local good, err = pcall(func)
pos = old_pos

@ -1,34 +0,0 @@
language: python
sudo: false
env:
- LUA="lua=5.1"
- LUA="lua=5.2"
- LUA="lua=5.3"
- LUA="luajit=2.0"
- LUA="luajit=2.1"
before_install:
- pip install hererocks
- hererocks lua_install -r^ --$LUA
- export PATH=$PATH:$PWD/lua_install/bin # Add directory with all installed binaries to PATH
install:
- luarocks install busted
- luarocks install luacov
- luarocks install luacov-coveralls
script:
- busted --verbose --coverage
after_success:
- luacov-coveralls --exclude $TRAVIS_BUILD_DIR/lua_install
branches:
except:
- gh-pages
notifications:
email:
on_success: change
on_failure: always

@ -1,5 +0,0 @@
# 1.1.0
* Fixes error with long strings in Lua 5.1 (@pgimeno)
* Adds incremental mode (@pgimeno)

@ -1,20 +0,0 @@
Copyright (c) 2013 Enrique García Cota + Adam Baldwin + hanzao + Equi 4 Software
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -1,55 +0,0 @@
md5.lua [![Build Status](https://travis-ci.org/kikito/md5.lua.svg)](https://travis-ci.org/kikito/md5.lua)
=========================================================================================================
This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1.
It implements md5.sum and md5.sumhex like the [kernel project md5 package](http://www.keplerproject.org/md5/), but it's done completely in Lua, with no dependencies on other libs or C files.
Usage
=====
Simple example:
local md5 = require 'md5'
local md5_as_data = md5.sum(message) -- returns raw bytes
local md5_as_hex = md5.sumhexa(message) -- returns a hex string
local md5_as_hex2 = md5.tohex(md5_as_data) -- returns the same string as md5_as_hex
Incremental example (for computing md5 of streams, or big files which have to be loaded in chunks - new since 1.1.0):
local m = md5.new()
m:update('some bytes')
m:update('some more bytes')
m:update('etc')
return md5.tohex(m:finish())
Credits
=======
This is a cleanup of an implementation by Adam Baldwin - https://gist.github.com/evilpacket/3647908
Which in turn was a mix of the bitwise lib, http://luaforge.net/projects/bit/ by hanzhao (`abrash_han - at - hotmail.com`),
and http://equi4.com/md5/md5calc.lua, by Equi 4 Software.
Lua 5.2 and LuaJIT compatibility by [Positive07](https://github.com/kikito/md5.lua/pull/2)
A very important fix and the incremental variant by [pgimeno](https://github.com/kikito/md5.lua/pull/10)
License
=======
This library, as well as all the previous ones in which is based, is released under the MIT license (See license file for details).
Specs
=====
The specs for this library are implemented with [busted](http://ovinelabs.com/busted/). In order to run them, install busted and then:
cd path/to/where/the/spec/folder/is
busted

@ -1,396 +0,0 @@
local md5 = {
_VERSION = "md5.lua 1.1.0",
_DESCRIPTION = "MD5 computation in Lua (5.1-3, LuaJIT)",
_URL = "https://github.com/kikito/md5.lua",
_LICENSE = [[
MIT LICENSE
Copyright (c) 2013 Enrique García Cota + Adam Baldwin + hanzao + Equi 4 Software
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
}
-- bit lib implementions
local char, byte, format, rep, sub =
string.char, string.byte, string.format, string.rep, string.sub
local bit_or, bit_and, bit_not, bit_xor, bit_rshift, bit_lshift
local ok, bit = pcall(require, 'bit')
if ok then
bit_or, bit_and, bit_not, bit_xor, bit_rshift, bit_lshift = bit.bor, bit.band, bit.bnot, bit.bxor, bit.rshift, bit.lshift
else
ok, bit = pcall(require, 'bit32')
if ok then
bit_not = bit.bnot
local tobit = function(n)
return n <= 0x7fffffff and n or -(bit_not(n) + 1)
end
local normalize = function(f)
return function(a,b) return tobit(f(tobit(a), tobit(b))) end
end
bit_or, bit_and, bit_xor = normalize(bit.bor), normalize(bit.band), normalize(bit.bxor)
bit_rshift, bit_lshift = normalize(bit.rshift), normalize(bit.lshift)
else
local function tbl2number(tbl)
local result = 0
local power = 1
for i = 1, #tbl do
result = result + tbl[i] * power
power = power * 2
end
return result
end
local function expand(t1, t2)
local big, small = t1, t2
if(#big < #small) then
big, small = small, big
end
-- expand small
for i = #small + 1, #big do
small[i] = 0
end
end
local to_bits -- needs to be declared before bit_not
bit_not = function(n)
local tbl = to_bits(n)
local size = math.max(#tbl, 32)
for i = 1, size do
if(tbl[i] == 1) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
-- defined as local above
to_bits = function (n)
if(n < 0) then
-- negative
return to_bits(bit_not(math.abs(n)) + 1)
end
-- to bits table
local tbl = {}
local cnt = 1
local last
while n > 0 do
last = n % 2
tbl[cnt] = last
n = (n-last)/2
cnt = cnt + 1
end
return tbl
end
bit_or = function(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
for i = 1, #tbl_m do
if(tbl_m[i]== 0 and tbl_n[i] == 0) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
bit_and = function(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
for i = 1, #tbl_m do
if(tbl_m[i]== 0 or tbl_n[i] == 0) then
tbl[i] = 0
else
tbl[i] = 1
end
end
return tbl2number(tbl)
end
bit_xor = function(m, n)
local tbl_m = to_bits(m)
local tbl_n = to_bits(n)
expand(tbl_m, tbl_n)
local tbl = {}
for i = 1, #tbl_m do
if(tbl_m[i] ~= tbl_n[i]) then
tbl[i] = 1
else
tbl[i] = 0
end
end
return tbl2number(tbl)
end
bit_rshift = function(n, bits)
local high_bit = 0
if(n < 0) then
-- negative
n = bit_not(math.abs(n)) + 1
high_bit = 0x80000000
end
local floor = math.floor
for i=1, bits do
n = n/2
n = bit_or(floor(n), high_bit)
end
return floor(n)
end
bit_lshift = function(n, bits)
if(n < 0) then
-- negative
n = bit_not(math.abs(n)) + 1
end
for i=1, bits do
n = n*2
end
return bit_and(n, 0xFFFFFFFF)
end
end
end
-- convert little-endian 32-bit int to a 4-char string
local function lei2str(i)
local f=function (s) return char( bit_and( bit_rshift(i, s), 255)) end
return f(0)..f(8)..f(16)..f(24)
end
-- convert raw string to big-endian int
local function str2bei(s)
local v=0
for i=1, #s do
v = v * 256 + byte(s, i)
end
return v
end
-- convert raw string to little-endian int
local function str2lei(s)
local v=0
for i = #s,1,-1 do
v = v*256 + byte(s, i)
end
return v
end
-- cut up a string in little-endian ints of given size
local function cut_le_str(s,...)
local o, r = 1, {}
local args = {...}
for i=1, #args do
table.insert(r, str2lei(sub(s, o, o + args[i] - 1)))
o = o + args[i]
end
return r
end
local swap = function (w) return str2bei(lei2str(w)) end
-- An MD5 mplementation in Lua, requires bitlib (hacked to use LuaBit from above, ugh)
-- 10/02/2001 jcw@equi4.com
local CONSTS = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
}
local f=function (x,y,z) return bit_or(bit_and(x,y),bit_and(-x-1,z)) end
local g=function (x,y,z) return bit_or(bit_and(x,z),bit_and(y,-z-1)) end
local h=function (x,y,z) return bit_xor(x,bit_xor(y,z)) end
local i=function (x,y,z) return bit_xor(y,bit_or(x,-z-1)) end
local z=function (ff,a,b,c,d,x,s,ac)
a=bit_and(a+ff(b,c,d)+x+ac,0xFFFFFFFF)
-- be *very* careful that left shift does not cause rounding!
return bit_or(bit_lshift(bit_and(a,bit_rshift(0xFFFFFFFF,s)),s),bit_rshift(a,32-s))+b
end
local function transform(A,B,C,D,X)
local a,b,c,d=A,B,C,D
local t=CONSTS
a=z(f,a,b,c,d,X[ 0], 7,t[ 1])
d=z(f,d,a,b,c,X[ 1],12,t[ 2])
c=z(f,c,d,a,b,X[ 2],17,t[ 3])
b=z(f,b,c,d,a,X[ 3],22,t[ 4])
a=z(f,a,b,c,d,X[ 4], 7,t[ 5])
d=z(f,d,a,b,c,X[ 5],12,t[ 6])
c=z(f,c,d,a,b,X[ 6],17,t[ 7])
b=z(f,b,c,d,a,X[ 7],22,t[ 8])
a=z(f,a,b,c,d,X[ 8], 7,t[ 9])
d=z(f,d,a,b,c,X[ 9],12,t[10])
c=z(f,c,d,a,b,X[10],17,t[11])
b=z(f,b,c,d,a,X[11],22,t[12])
a=z(f,a,b,c,d,X[12], 7,t[13])
d=z(f,d,a,b,c,X[13],12,t[14])
c=z(f,c,d,a,b,X[14],17,t[15])
b=z(f,b,c,d,a,X[15],22,t[16])
a=z(g,a,b,c,d,X[ 1], 5,t[17])
d=z(g,d,a,b,c,X[ 6], 9,t[18])
c=z(g,c,d,a,b,X[11],14,t[19])
b=z(g,b,c,d,a,X[ 0],20,t[20])
a=z(g,a,b,c,d,X[ 5], 5,t[21])
d=z(g,d,a,b,c,X[10], 9,t[22])
c=z(g,c,d,a,b,X[15],14,t[23])
b=z(g,b,c,d,a,X[ 4],20,t[24])
a=z(g,a,b,c,d,X[ 9], 5,t[25])
d=z(g,d,a,b,c,X[14], 9,t[26])
c=z(g,c,d,a,b,X[ 3],14,t[27])
b=z(g,b,c,d,a,X[ 8],20,t[28])
a=z(g,a,b,c,d,X[13], 5,t[29])
d=z(g,d,a,b,c,X[ 2], 9,t[30])
c=z(g,c,d,a,b,X[ 7],14,t[31])
b=z(g,b,c,d,a,X[12],20,t[32])
a=z(h,a,b,c,d,X[ 5], 4,t[33])
d=z(h,d,a,b,c,X[ 8],11,t[34])
c=z(h,c,d,a,b,X[11],16,t[35])
b=z(h,b,c,d,a,X[14],23,t[36])
a=z(h,a,b,c,d,X[ 1], 4,t[37])
d=z(h,d,a,b,c,X[ 4],11,t[38])
c=z(h,c,d,a,b,X[ 7],16,t[39])
b=z(h,b,c,d,a,X[10],23,t[40])
a=z(h,a,b,c,d,X[13], 4,t[41])
d=z(h,d,a,b,c,X[ 0],11,t[42])
c=z(h,c,d,a,b,X[ 3],16,t[43])
b=z(h,b,c,d,a,X[ 6],23,t[44])
a=z(h,a,b,c,d,X[ 9], 4,t[45])
d=z(h,d,a,b,c,X[12],11,t[46])
c=z(h,c,d,a,b,X[15],16,t[47])
b=z(h,b,c,d,a,X[ 2],23,t[48])
a=z(i,a,b,c,d,X[ 0], 6,t[49])
d=z(i,d,a,b,c,X[ 7],10,t[50])
c=z(i,c,d,a,b,X[14],15,t[51])
b=z(i,b,c,d,a,X[ 5],21,t[52])
a=z(i,a,b,c,d,X[12], 6,t[53])
d=z(i,d,a,b,c,X[ 3],10,t[54])
c=z(i,c,d,a,b,X[10],15,t[55])
b=z(i,b,c,d,a,X[ 1],21,t[56])
a=z(i,a,b,c,d,X[ 8], 6,t[57])
d=z(i,d,a,b,c,X[15],10,t[58])
c=z(i,c,d,a,b,X[ 6],15,t[59])
b=z(i,b,c,d,a,X[13],21,t[60])
a=z(i,a,b,c,d,X[ 4], 6,t[61])
d=z(i,d,a,b,c,X[11],10,t[62])
c=z(i,c,d,a,b,X[ 2],15,t[63])
b=z(i,b,c,d,a,X[ 9],21,t[64])
return bit_and(A+a,0xFFFFFFFF),bit_and(B+b,0xFFFFFFFF),
bit_and(C+c,0xFFFFFFFF),bit_and(D+d,0xFFFFFFFF)
end
----------------------------------------------------------------
local function md5_update(self, s)
self.pos = self.pos + #s
s = self.buf .. s
for ii = 1, #s - 63, 64 do
local X = cut_le_str(sub(s,ii,ii+63),4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4)
assert(#X == 16)
X[0] = table.remove(X,1) -- zero based!
self.a,self.b,self.c,self.d = transform(self.a,self.b,self.c,self.d,X)
end
self.buf = sub(s, math.floor(#s/64)*64 + 1, #s)
return self
end
local function md5_finish(self)
local msgLen = self.pos
local padLen = 56 - msgLen % 64
if msgLen % 64 > 56 then padLen = padLen + 64 end
if padLen == 0 then padLen = 64 end
local s = char(128) .. rep(char(0),padLen-1) .. lei2str(bit_and(8*msgLen, 0xFFFFFFFF)) .. lei2str(math.floor(msgLen/0x20000000))
md5_update(self, s)
assert(self.pos % 64 == 0)
return lei2str(self.a) .. lei2str(self.b) .. lei2str(self.c) .. lei2str(self.d)
end
----------------------------------------------------------------
function md5.new()
return { a = CONSTS[65], b = CONSTS[66], c = CONSTS[67], d = CONSTS[68],
pos = 0,
buf = '',
update = md5_update,
finish = md5_finish }
end
function md5.tohex(s)
return format("%08x%08x%08x%08x", str2bei(sub(s, 1, 4)), str2bei(sub(s, 5, 8)), str2bei(sub(s, 9, 12)), str2bei(sub(s, 13, 16)))
end
function md5.sum(s)
return md5.new():update(s):finish()
end
function md5.sumhexa(s)
return md5.tohex(md5.sum(s))
end
return md5

@ -1,21 +0,0 @@
package = "md5"
version = "1.0-0"
source = {
url = "https://github.com/kikito/md5.lua/archive/v1.0.0.tar.gz",
dir = "md5.lua-1.0.0"
}
description = {
summary = "MD5 sum in pure Lua, with no C and no external dependencies",
detailed = "This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1",
homepage = "https://github.com/kikito/md5.lua",
license = "MIT"
}
dependencies = {
"lua >= 5.1"
}
build = {
type = "builtin",
modules = {
md5 = "md5.lua"
}
}

@ -1,21 +0,0 @@
package = "md5"
version = "1.0-1"
source = {
url = "https://github.com/kikito/md5.lua/archive/v1.0.1.tar.gz",
dir = "md5.lua-1.0.1"
}
description = {
summary = "MD5 sum in pure Lua, with no C and no external dependencies",
detailed = "This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1",
homepage = "https://github.com/kikito/md5.lua",
license = "MIT"
}
dependencies = {
"lua >= 5.1"
}
build = {
type = "builtin",
modules = {
md5 = "md5.lua"
}
}

@ -1,21 +0,0 @@
package = "md5"
version = "1.0-2"
source = {
url = "https://github.com/kikito/md5.lua/archive/v1.0.2.tar.gz",
dir = "md5.lua-1.0.2"
}
description = {
summary = "MD5 sum in pure Lua, with no C and no external dependencies",
detailed = "This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1",
homepage = "https://github.com/kikito/md5.lua",
license = "MIT"
}
dependencies = {
"lua >= 5.1"
}
build = {
type = "builtin",
modules = {
md5 = "md5.lua"
}
}

@ -1,21 +0,0 @@
package = "md5"
version = "1.1-0"
source = {
url = "https://github.com/kikito/md5.lua/archive/v1.1.0.tar.gz",
dir = "md5.lua-1.1.0"
}
description = {
summary = "MD5 sum in pure Lua, with no C and no external dependencies",
detailed = "This pure-Lua module computes md5 in Lua 5.1, Lua 5.2 and LuaJIT, using native bit-manipulation libraries when available, and falling back to table-based manipulation of integers in 5.1",
homepage = "https://github.com/kikito/md5.lua",
license = "MIT"
}
dependencies = {
"lua >= 5.1"
}
build = {
type = "builtin",
modules = {
md5 = "md5.lua"
}
}

@ -1,40 +0,0 @@
local md5 = require('md5')
local function hex2bin(hex)
local result, _ = hex:gsub('..', function(hexval)
return string.char(tonumber(hexval, 16))
end)
return result
end
describe('md5', function()
describe('md5.sumhexa', function()
it('works', function()
assert.equal(md5.sumhexa("asdf"), '912ec803b2ce49e4a541068d495ab570')
assert.equal(md5.sumhexa('The quick brown fox jumps over the lazy dog'), '9e107d9d372bb6826bd81d3542a419d6')
assert.equal(md5.sumhexa('The quick brown fox jumps over the lazy dog.'), 'e4d909c290d0fb1ca068ffaddf22cbd0')
assert.equal(md5.sumhexa(''), 'd41d8cd98f00b204e9800998ecf8427e')
assert.equal(md5.sumhexa(('1'):rep(824)), 'a126fd3611ab8d9b7e8a3384e2fa78a0')
assert.equal(md5.sumhexa(('1'):rep(1528)), '3750b6a29d923b633e05d6ae76895664')
local state = md5.new()
state:update('Hello')
state:update(', World!')
assert.equal(md5.tohex(state:finish()), '65a8e27d8879283831b664bd8b7f0ad4')
end)
end)
describe('md5.sum', function()
it('works', function()
assert.equal(md5.sum("asdf"), hex2bin '912ec803b2ce49e4a541068d495ab570')
assert.equal(md5.sum('The quick brown fox jumps over the lazy dog'), hex2bin '9e107d9d372bb6826bd81d3542a419d6')
assert.equal(md5.sum('The quick brown fox jumps over the lazy dog.'), hex2bin 'e4d909c290d0fb1ca068ffaddf22cbd0')
assert.equal(md5.sum(''), hex2bin 'd41d8cd98f00b204e9800998ecf8427e')
assert.equal(md5.sum(('1'):rep(824)), hex2bin 'a126fd3611ab8d9b7e8a3384e2fa78a0')
assert.equal(md5.sum(('1'):rep(1528)), hex2bin '3750b6a29d923b633e05d6ae76895664')
local state = md5.new()
state:update('Hello')
state:update(', World!')
assert.equal(state:finish(), hex2bin '65a8e27d8879283831b664bd8b7f0ad4')
end)
end)
end)

@ -28,6 +28,30 @@ function moremesecons.setting(modname, settingname, default, min)
end
end
-- Storage helpers
function moremesecons.get_storage_data(storage, name)
return {
tab = minetest.deserialize(storage:get_string(name)) or {},
name = name,
storage = storage
}
end
function moremesecons.set_data_to_pos(sto, pos, data)
sto.tab[minetest.hash_node_position(pos)] = data
sto.storage:set_string(sto.name, minetest.serialize(sto.tab))
end
function moremesecons.get_data_from_pos(sto, pos)
return sto.tab[minetest.hash_node_position(pos)]
end
function moremesecons.remove_data_from_pos(sto, pos)
sto.tab[minetest.hash_node_position(pos)] = nil
sto.storage:set_string(sto.name, minetest.serialize(sto.tab))
end
-- Vector helpers
-- All the following functions are from the vector_extras mod (https://github.com/HybridDog/vector_extras).
-- If you enable that mod, its functions will be used instead of the ones defined below