summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2012-11-22 15:50:00 +0100
committerantirez <antirez@gmail.com>2012-11-22 15:51:01 +0100
commit9120275dc94dfb6b24773412d26d7de70a5675a1 (patch)
tree0511c059afcff93d4e2a9ab1ce2b2eec0ea6554e
parentde00a5a0929da097ecd46612e83b482698419f08 (diff)
downloadredis-9120275dc94dfb6b24773412d26d7de70a5675a1.tar.gz
EVALSHA is now case insensitive.
EVALSHA used to crash if the SHA1 was not lowercase (Issue #783). Fixed using a case insensitive dictionary type for the sha -> script map used for replication of scripts.
-rw-r--r--src/redis.c13
-rw-r--r--src/redis.h1
-rw-r--r--src/scripting.c2
-rw-r--r--tests/unit/scripting.tcl4
4 files changed, 18 insertions, 2 deletions
diff --git a/src/redis.c b/src/redis.c
index c4c1adb0b..eb4418e77 100644
--- a/src/redis.c
+++ b/src/redis.c
@@ -391,7 +391,8 @@ int dictSdsKeyCompare(void *privdata, const void *key1,
return memcmp(key1, key2, l1) == 0;
}
-/* A case insensitive version used for the command lookup table. */
+/* A case insensitive version used for the command lookup table and other
+ * places where case insensitive non binary-safe comparison is needed. */
int dictSdsKeyCaseCompare(void *privdata, const void *key1,
const void *key2)
{
@@ -506,6 +507,16 @@ dictType dbDictType = {
dictRedisObjectDestructor /* val destructor */
};
+/* server.lua_scripts sha (as sds string) -> scripts (as robj) cache. */
+dictType shaScriptObjectDictType = {
+ dictSdsCaseHash, /* hash function */
+ NULL, /* key dup */
+ NULL, /* val dup */
+ dictSdsKeyCaseCompare, /* key compare */
+ dictSdsDestructor, /* key destructor */
+ dictRedisObjectDestructor /* val destructor */
+};
+
/* Db->expires */
dictType keyptrDictType = {
dictSdsHash, /* hash function */
diff --git a/src/redis.h b/src/redis.h
index b75e4bd82..8fd6f447d 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -755,6 +755,7 @@ extern struct sharedObjectsStruct shared;
extern dictType setDictType;
extern dictType zsetDictType;
extern dictType dbDictType;
+extern dictType shaScriptObjectDictType;
extern double R_Zero, R_PosInf, R_NegInf, R_Nan;
extern dictType hashDictType;
diff --git a/src/scripting.c b/src/scripting.c
index 23404338b..d614f42a1 100644
--- a/src/scripting.c
+++ b/src/scripting.c
@@ -532,7 +532,7 @@ void scriptingInit(void) {
/* Initialize a dictionary we use to map SHAs to scripts.
* This is useful for replication, as we need to replicate EVALSHA
* as EVAL, so we need to remember the associated script. */
- server.lua_scripts = dictCreate(&dbDictType,NULL);
+ server.lua_scripts = dictCreate(&shaScriptObjectDictType,NULL);
/* Register the redis commands table and fields */
lua_newtable(lua);
diff --git a/tests/unit/scripting.tcl b/tests/unit/scripting.tcl
index f96d0fc64..f1df11f3c 100644
--- a/tests/unit/scripting.tcl
+++ b/tests/unit/scripting.tcl
@@ -47,6 +47,10 @@ start_server {tags {"scripting"}} {
r evalsha 9bd632c7d33e571e9f24556ebed26c3479a87129 0
} {myval}
+ test {EVALSHA - Can we call a SHA1 in uppercase?} {
+ r evalsha 9BD632C7D33E571E9F24556EBED26C3479A87129 0
+ } {myval}
+
test {EVALSHA - Do we get an error on invalid SHA1?} {
catch {r evalsha NotValidShaSUM 0} e
set _ $e