]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Minor] Some tests fixes
authorVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 23 Sep 2025 10:56:54 +0000 (11:56 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 23 Sep 2025 10:56:54 +0000 (11:56 +0100)
src/lua/lua_archive.c
test/lua/unit/archive.lua

index fa67d60617472db5236dfb021e0789099d10e672..7752b549ea63a6f886c9db10ebaf1c194236b5f8 100644 (file)
@@ -216,7 +216,15 @@ lua_archive_zip_encrypt(lua_State *L)
 {
        LUA_TRACE_POINT;
        luaL_checktype(L, 1, LUA_TTABLE);
-       const char *password = luaL_checkstring(L, 2);
+       const char *password = NULL;
+       if (lua_gettop(L) >= 2 && !lua_isnil(L, 2)) {
+               if (lua_type(L, 2) == LUA_TSTRING) {
+                       password = lua_tostring(L, 2);
+               }
+               else {
+                       return luaL_error(L, "invalid password (string expected)");
+               }
+       }
        GArray *specs = g_array_sized_new(FALSE, FALSE, sizeof(struct rspamd_zip_file_spec), 8);
        GError *err = NULL;
 
@@ -601,10 +609,11 @@ lua_archive_pack(lua_State *L)
 }
 
 /***
- * @function archive.unpack(data[, format])
+ * @function archive.unpack(data[, format][, password])
  * Unpacks an archive from a Lua string (or rspamd_text) using libarchive.
  * @param {string|text} data archive contents
  * @param {string} format optional format name to restrict autodetection (e.g. "zip")
+ * @param {string} password optional password for encrypted archives (e.g. ZIP AES)
  * @return {table} array of files: { name = string, content = text } (non-regular entries are skipped)
  */
 static int
@@ -613,6 +622,7 @@ lua_archive_unpack(lua_State *L)
        LUA_TRACE_POINT;
        struct rspamd_lua_text *t = NULL;
        const char *format = NULL;
+       const char *password = NULL;
        struct archive *a = NULL;
 
        t = lua_check_text_or_string(L, 1);
@@ -624,6 +634,9 @@ lua_archive_unpack(lua_State *L)
        if (lua_type(L, 2) == LUA_TSTRING) {
                format = lua_tostring(L, 2);
        }
+       if (lua_type(L, 3) == LUA_TSTRING) {
+               password = lua_tostring(L, 3);
+       }
 
        a = archive_read_new();
        if (a == NULL) {
@@ -639,6 +652,17 @@ lua_archive_unpack(lua_State *L)
                archive_read_support_format_all(a);
        }
 
+       if (password && *password) {
+               /* supply passphrase for encrypted archives (e.g. zip AES) */
+               int pr = archive_read_add_passphrase(a, password);
+               if (pr != ARCHIVE_OK) {
+                       const char *aerr = archive_error_string(a);
+                       lua_pushfstring(L, "cannot set passphrase: %s", aerr ? aerr : "unknown error");
+                       archive_read_free(a);
+                       return lua_error(L);
+               }
+       }
+
        int r = archive_read_open_memory(a, t->start, t->len);
        if (r != ARCHIVE_OK) {
                const char *aerr = archive_error_string(a);
index fe194322c92a4bf5c0ad6dcf8d8d8546fd663472..d52d14e577a92a8b00b3f2e935ee30e72403a4e0 100644 (file)
@@ -53,7 +53,7 @@ context("Lua archive bindings", function()
     local blob = archive.zip_encrypt(files, pwd)
     assert_equal(type(blob), "userdata")
     -- libarchive can read AE-2, so unpack should succeed and yield the same files
-    local out = archive.unpack(blob, "zip")
+    local out = archive.unpack(blob, "zip", pwd)
     assert_equal(#out, 2)
     local names = {}
     for _, f in ipairs(out) do names[f.name] = f.content end
@@ -61,6 +61,19 @@ context("Lua archive bindings", function()
     assert_rspamd_eq({ actual = names["y.bin"], expect = rspamd_text.fromstring("\001\002\003") })
   end)
 
+  test("zip_encrypt with wrong password fails to unpack", function()
+    local files = {
+      { name = "secret.txt", content = "topsecret" },
+    }
+    local pwd = "goodpass"
+    local blob = archive.zip_encrypt(files, pwd)
+    assert_equal(type(blob), "userdata")
+    local ok, err = pcall(function()
+      archive.unpack(blob, "zip", "badpass")
+    end)
+    assert_equal(ok, false)
+  end)
+
   test("tar/untar helpers roundtrip (no compression)", function()
     local files = {
       { name = "x.txt", content = "X" },