Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: SCAN commands have results in lua script indexed at 0, missing first element when iterating #1345

Open
moritzraho opened this issue May 29, 2024 · 0 comments

Comments

@moritzraho
Copy link

moritzraho commented May 29, 2024

Reproduce

From the REPL (> node)

Redis = require('ioredis-mock'); redis = new Redis()
redis.defineCommand('scanWrapper', { lua: `local res = redis.call('SCAN', '0') for idx, member in ipairs(res[2]) do print(idx, member) end return res[2]` })
await redis.mset('a', '1', 'b', '2'); await redis.scanWrapper()

prints

1       b
at index 0 (wrong)      a

instead of expected

1        a
2       b
at index 0 (wrong)      nil

and returns

['b']

instead of

['a', 'b']

Patch (dirty)

for bundled v8.9.0 (with npx patch-package ioredis-mock)

diff --git a/node_modules/ioredis-mock/lib/index.js b/node_modules/ioredis-mock/lib/index.js
index a82c297..ac6fd63 100644
--- a/node_modules/ioredis-mock/lib/index.js
+++ b/node_modules/ioredis-mock/lib/index.js
@@ -3748,6 +3748,16 @@ var import_fengari = __toESM(require("fengari")), import_fengari_interop = __toE
 }, makeReturnValue = (L) => {
   if (!isTopArray(L)()) {
     let retVal2 = import_fengari_interop.default.tojs(L, -1);
+    // hack to support *scan commands
+    if (lua.lua_istable(L, -1)) {
+      lua.lua_len(L, -1);
+      let length = lua.lua_tointeger(L, -1);
+      retValArray = []
+      for (let i = 1; i <= length; i++) {
+        retValArray.push(retVal2.get(i))
+      }
+      return retValArray
+    }
     return Array.isArray(retVal2) ? retVal2.slice(1) : retVal2;
   }
   let arrayLength = getTopLength(L), table = import_fengari_interop.default.tojs(L, -1), retVal = [];
@@ -3830,9 +3840,15 @@ var { lua: lua2, to_luastring: toLuaString2 } = import_fengari2.default, defineR
       throw err;
     return import_fengari_interop2.default.push(vm.L, ["error", err.toString()]), 1;
   }
-  return result || result === 0 ? (Array.isArray(result) && (result.unshift(null), result[Symbol.for("__len")] = function() {
+  return result || result === 0 ? (
+    Array.isArray(result) && (result.unshift(null), result[Symbol.for("__len")] = function() {
+    return this.length - 1;
+  }),
+  Array.isArray(result[2]) && (result[2].unshift(null), result[2][Symbol.for("__len")] = function() {
     return this.length - 1;
-  }), import_fengari_interop2.default.push(vm.L, result), 1) : 0;
+  })
+  ,import_fengari_interop2.default.push(vm.L, result), 1
+) : 0;
 };
 function defineKeys(vm, numberOfKeys, commandArgs) {
   let keys2 = commandArgs.slice(0, numberOfKeys);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant