From: Rob Blanckaert <basicer@basicer.com>
Date: Mon, 30 Oct 2017 07:18:18 +0000 (-0700)
Subject: Add sha1 to lua utils. (#6563)
X-Git-Tag: 0.4.17~63
X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=4d9bf75d3ab6a181b3113c3231d2e41245795a60;p=oweals%2Fminetest.git

Add sha1 to lua utils. (#6563)
---

diff --git a/doc/client_lua_api.md b/doc/client_lua_api.md
index ab72bbccf..8ef3bfb2e 100644
--- a/doc/client_lua_api.md
+++ b/doc/client_lua_api.md
@@ -628,6 +628,9 @@ Minetest namespace reference
   version entirely. To check for the presence of engine features, test
   whether the functions exported by the wanted features exist. For example:
   `if minetest.nodeupdate then ... end`.
+* `minetest.sha1(data, [raw])`: returns the sha1 hash of data
+    * `data`: string of data to hash
+    * `raw`: return raw bytes instead of hex digits, default: false
 
 ### Logging
 * `minetest.debug(...)`
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index d6b8fc5bb..13881ef70 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -2234,6 +2234,9 @@ Helper functions
   version entirely. To check for the presence of engine features, test
   whether the functions exported by the wanted features exist. For example:
   `if minetest.nodeupdate then ... end`.
+* `minetest.sha1(data, [raw])`: returns the sha1 hash of data
+    * `data`: string of data to hash
+    * `raw`: return raw bytes instead of hex digits, default: false
 
 ### Logging
 * `minetest.debug(...)`
diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp
index c4a988e07..901105fe0 100644
--- a/src/script/lua_api/l_util.cpp
+++ b/src/script/lua_api/l_util.cpp
@@ -36,6 +36,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/base64.h"
 #include "config.h"
 #include "version.h"
+#include "util/hex.h"
+#include "util/sha1.h"
 #include <algorithm>
 
 
@@ -422,6 +424,32 @@ int ModApiUtil::l_get_version(lua_State *L)
 	return 1;
 }
 
+int ModApiUtil::l_sha1(lua_State *L)
+{
+	NO_MAP_LOCK_REQUIRED;
+	size_t size;
+	const char *data = luaL_checklstring(L, 1, &size);
+	bool hex = !lua_isboolean(L, 2) || !lua_toboolean(L, 2);
+
+	// Compute actual checksum of data
+	std::string data_sha1;
+	{
+		SHA1 ctx;
+		ctx.addBytes(data, size);
+		unsigned char *data_tmpdigest = ctx.getDigest();
+		data_sha1.assign((char*) data_tmpdigest, 20);
+		free(data_tmpdigest);
+	}
+
+	if (hex) {
+		std::string sha1_hex = hex_encode(data_sha1);
+		lua_pushstring(L, sha1_hex.c_str());
+	} else {
+		lua_pushlstring(L, data_sha1.data(), data_sha1.size());
+	}
+
+	return 1;
+}
 
 void ModApiUtil::Initialize(lua_State *L, int top)
 {
@@ -454,6 +482,7 @@ void ModApiUtil::Initialize(lua_State *L, int top)
 	API_FCT(decode_base64);
 
 	API_FCT(get_version);
+	API_FCT(sha1);
 
 	LuaSettings::create(L, g_settings, g_settings_path);
 	lua_setfield(L, top, "settings");
@@ -479,6 +508,7 @@ void ModApiUtil::InitializeClient(lua_State *L, int top)
 	API_FCT(decode_base64);
 
 	API_FCT(get_version);
+	API_FCT(sha1);
 }
 
 void ModApiUtil::InitializeAsync(lua_State *L, int top)
@@ -504,6 +534,7 @@ void ModApiUtil::InitializeAsync(lua_State *L, int top)
 	API_FCT(decode_base64);
 
 	API_FCT(get_version);
+	API_FCT(sha1);
 
 	LuaSettings::create(L, g_settings, g_settings_path);
 	lua_setfield(L, top, "settings");
diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h
index b75d9db29..16f4edea8 100644
--- a/src/script/lua_api/l_util.h
+++ b/src/script/lua_api/l_util.h
@@ -93,6 +93,9 @@ private:
 	// get_version()
 	static int l_get_version(lua_State *L);
 
+	// sha1(string, raw)
+	static int l_sha1(lua_State *L);
+
 public:
 	static void Initialize(lua_State *L, int top);
 	static void InitializeAsync(lua_State *L, int top);