From 7917ec4626204b6e3ea6f5c07c6135f33eb394d5 Mon Sep 17 00:00:00 2001 From: Allen Samuels Date: Wed, 19 Aug 2026 19:17:38 +0000 Subject: [PATCH 1/2] Fix issue #4476 Signed-off-by: Allen Samuels --- src/t_hash.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/t_hash.c b/src/t_hash.c index 6c3049cecec..f666caebf48 100644 --- a/src/t_hash.c +++ b/src/t_hash.c @@ -322,6 +322,7 @@ bool hashTypeHasStringRef(robj *o, sds field) { if (objectGetEncoding(o) == OBJ_ENCODING_LISTPACK) return false; hashtable *ht = objectGetVal(o); void **entry_ref = hashtableFindRef(ht, field); + if (!entry_ref) return false; return (entryHasStringRef(*entry_ref)); } From 00179d78a43025ab3602fc03070aa27ee6cd3454 Mon Sep 17 00:00:00 2001 From: Allen Samuels Date: Wed, 19 Aug 2026 22:53:30 +0000 Subject: [PATCH 2/2] Add test for hashTypeHasStringRef with a non-existent field hashTypeHasStringRef() returns early for listpack-encoded hashes, so the NULL entry_ref deref is only reachable once the hash is converted to the hashtable encoding. The test sets a stringref to force that conversion, then queries a field that does not exist. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01FS8pBvk33tMU16JM5q1tB9 Signed-off-by: Allen Samuels --- tests/unit/moduleapi/hash_stringref.tcl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/unit/moduleapi/hash_stringref.tcl b/tests/unit/moduleapi/hash_stringref.tcl index a2efb23cc8b..1c517c78671 100644 --- a/tests/unit/moduleapi/hash_stringref.tcl +++ b/tests/unit/moduleapi/hash_stringref.tcl @@ -14,6 +14,17 @@ start_server {tags {"modules"}} { assert_equal "1" [r hash.has_stringref k f] } + test {Module hash has_stringref on non-existent field} { + r del k + r hset k f hello1 + # Setting a stringref converts the hash to the hashtable encoding, which + # is the only encoding that looks the field up in the hashtable. + r hash.set_stringref k f hello1 + assert_encoding hashtable k + # Missing field must return 0 rather than dereferencing a NULL entry. + assert_equal "0" [r hash.has_stringref k nonexistent] + } + test "Unload the module - hash" { assert_equal {OK} [r module unload hash.stringref] }