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.
This commit is contained in:
antirez 2012-11-22 15:50:00 +01:00
parent cceb0c5b4a
commit 95f68f7b0f
4 changed files with 18 additions and 2 deletions

View File

@ -393,7 +393,8 @@ int dictSdsKeyCompare(void *privdata, const void *key1,
return memcmp(key1, key2, l1) == 0; 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, int dictSdsKeyCaseCompare(void *privdata, const void *key1,
const void *key2) const void *key2)
{ {
@ -508,6 +509,16 @@ dictType dbDictType = {
dictRedisObjectDestructor /* val destructor */ 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 */ /* Db->expires */
dictType keyptrDictType = { dictType keyptrDictType = {
dictSdsHash, /* hash function */ dictSdsHash, /* hash function */

View File

@ -890,6 +890,7 @@ extern dictType setDictType;
extern dictType zsetDictType; extern dictType zsetDictType;
extern dictType clusterNodesDictType; extern dictType clusterNodesDictType;
extern dictType dbDictType; extern dictType dbDictType;
extern dictType shaScriptObjectDictType;
extern double R_Zero, R_PosInf, R_NegInf, R_Nan; extern double R_Zero, R_PosInf, R_NegInf, R_Nan;
extern dictType hashDictType; extern dictType hashDictType;

View File

@ -532,7 +532,7 @@ void scriptingInit(void) {
/* Initialize a dictionary we use to map SHAs to scripts. /* Initialize a dictionary we use to map SHAs to scripts.
* This is useful for replication, as we need to replicate EVALSHA * This is useful for replication, as we need to replicate EVALSHA
* as EVAL, so we need to remember the associated script. */ * 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 */ /* Register the redis commands table and fields */
lua_newtable(lua); lua_newtable(lua);

View File

@ -47,6 +47,10 @@ start_server {tags {"scripting"}} {
r evalsha 9bd632c7d33e571e9f24556ebed26c3479a87129 0 r evalsha 9bd632c7d33e571e9f24556ebed26c3479a87129 0
} {myval} } {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?} { test {EVALSHA - Do we get an error on invalid SHA1?} {
catch {r evalsha NotValidShaSUM 0} e catch {r evalsha NotValidShaSUM 0} e
set _ $e set _ $e