Support RESP3 replies in redis.setresp(3) - #22
Conversation
fatal10110
left a comment
There was a problem hiding this comment.
RESP3 support looks solid and symmetric across the C encoder, C/TS decoders, and the type surface. The idx absolutization in encode_table correctly accounts for the new lua_getfield probes. Two minor findings below.
| } | ||
|
|
||
| if (type === REPLY_BIG_NUMBER) { | ||
| const payload = buffer.subarray(cursor, cursor + countOrLen); |
There was a problem hiding this comment.
REPLY_BIG_NUMBER decode skips the bounds check that every sibling RESP3 decoder here performs (BOOL/DOUBLE/VERBATIM all throw new Error("ERR reply decoding failed")), and that the C decoder does too (*offset + count_or_len > len). On a truncated/malformed buffer, buffer.subarray(cursor, cursor + countOrLen) silently clamps and you get a short big_number instead of an error. Add:
if (cursor + countOrLen > buffer.length) {
throw new Error("ERR reply decoding failed");
}| return 1; | ||
| uint32_t next = (uint32_t)luaL_checkinteger(L, 1); | ||
| if (next != 2 && next != 3) { | ||
| return luaL_error(L, "ERR RESP version must be 2 or 3."); |
There was a problem hiding this comment.
Redis's redis.setresp raises "RESP version must be 2 or 3." with no ERR prefix (src/script_lua.c luaSetResp). The added "ERR " here yields a spurious ERR code, deviating from the Redis-7 error fidelity the project targets. Drop the prefix to match.
decodeReply skipped the length check the sibling RESP3 decoders (BOOL/DOUBLE/VERBATIM) and the C decoder perform, so a truncated big_number silently produced a short payload instead of throwing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Correction on my earlier review: the second finding (drop the The first finding (big-number bounds check) is fixed in e07e4c1. |
Summary
ReplyValueshapes for booleans, doubles, maps, sets, big numbers, and verbatim strings.redis.setresp(3)enable RESP3 Lua conversions for the current script instead of rejecting it.redis.call/redis.pcall, and document the expanded ABI.Root Cause
redis.setresp(3)updated a protocol flag, but neither the C return encoder, host reply decoder, TypeScript codec, nor publicReplyValuetype could represent RESP3 values. The first PR draft avoided the silent no-op by rejecting RESP3; this update implements the missing representable RESP3 shapes instead.Real Redis Lua scripts can switch command reply conversion with
redis.setresp(3), but push replies are not ordinary values returned byredis.callor by the script itself. They are out-of-band server-to-client protocol frames, so this PR models the RESP3 value types scripts can actually consume/return and documents push as out of scope.Validation
node --test --import tsx --test-name-pattern "redis\\.setresp" test/engine.test.tsfailed because RESP3 conversions were not represented.node --test --import tsx --test-name-pattern "RESP3 values roundtrip" test/codec.test.tsfailed because RESP3 values fell through to bulk encoding.node --test --import tsx --test-name-pattern "redis\\.setresp|RESP3 values roundtrip" test/engine.test.ts test/codec.test.tspassed: 5/5.npm run buildpassed.npm testpassed: 175/175.docs/limits-compat.mdwording for RESP3 push scope.Fixes #9