Ensure empty error tables in scripts don't crash (#14163)

This PR is based on: https://github.com/valkey-io/valkey/pull/2229

When calling the command `EVAL error{} 0`, Redis crashes with the
following stack trace. This patch ensures we never leave the
`err_info.msg` field null when we fail to extract a proper error
message.

---------

Signed-off-by: Fusl <fusl@meo.ws>
Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Fusl <fusl@meo.ws>
Co-authored-by: Binbin <binloveplay1314@qq.com>
This commit is contained in:
debing.sun 2025-07-07 10:12:51 +08:00 committed by GitHub
parent 9ff8ade64a
commit 4322cebc17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 0 deletions

View file

@ -2,9 +2,14 @@
* Copyright (c) 2009-Present, Redis Ltd.
* All rights reserved.
*
* Copyright (c) 2024-present, Valkey contributors.
* All rights reserved.
*
* Licensed under your choice of (a) the Redis Source Available License 2.0
* (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the
* GNU Affero General Public License v3 (AGPLv3).
*
* Portions of this file are available under BSD3 terms; see REDISCONTRIBUTIONS for more information.
*/
#include "script_lua.h"
@ -1580,6 +1585,9 @@ void luaExtractErrorInformation(lua_State *lua, errorInfo *err_info) {
lua_getfield(lua, -1, "err");
if (lua_isstring(lua, -1)) {
err_info->msg = sdsnew(lua_tostring(lua, -1));
} else {
/* Ensure we never return a NULL msg. */
err_info->msg = sdsnew("ERR unknown error");
}
lua_pop(lua, 1);

View file

@ -1,3 +1,17 @@
#
# Copyright (c) 2009-Present, Redis Ltd.
# All rights reserved.
#
# Copyright (c) 2024-present, Valkey contributors.
# All rights reserved.
#
# Licensed under your choice of (a) the Redis Source Available License 2.0
# (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the
# GNU Affero General Public License v3 (AGPLv3).
#
# Portions of this file are available under BSD3 terms; see REDISCONTRIBUTIONS for more information.
#
foreach is_eval {0 1} {
if {$is_eval == 1} {
@ -2447,4 +2461,21 @@ start_server {tags {"scripting"}} {
assert { [r memory usage foo] <= $expected_memory};
}
}
test {EVAL - explicit error() call handling} {
# error("simple string error")
assert_error {ERR user_script:1: simple string error script: *} {
r eval "error('simple string error')" 0
}
# error({"err": "ERR table error"})
assert_error {ERR table error script: *} {
r eval "error({err='ERR table error'})" 0
}
# error({})
assert_error {ERR unknown error script: *} {
r eval "error({})" 0
}
}
}