From 3a063f58c8073ae9a434d3f6119644b8b6cf4aff Mon Sep 17 00:00:00 2001 From: Guy Benoish Date: Tue, 5 Nov 2019 19:23:37 +0530 Subject: [PATCH 1/5] Make sure Redis does not reply with negative zero --- src/util.c | 4 ++++ tests/unit/type/incr.tcl | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/src/util.c b/src/util.c index 2be42a0df..bd8f0fb98 100644 --- a/src/util.c +++ b/src/util.c @@ -602,6 +602,10 @@ int ld2string(char *buf, size_t len, long double value, ld2string_mode mode) { } if (*p == '.') l--; } + if (l == 2 && buf[0] == '-' && buf[1] == '0') { + buf[0] = '0'; + l = 1; + } break; default: return 0; /* Invalid mode. */ } diff --git a/tests/unit/type/incr.tcl b/tests/unit/type/incr.tcl index a58710d39..63bf2e116 100644 --- a/tests/unit/type/incr.tcl +++ b/tests/unit/type/incr.tcl @@ -151,4 +151,10 @@ start_server {tags {"incr"}} { catch {r incrbyfloat foo 1} err format $err } {ERR*valid*} + + test {No negative zero} { + r incrbyfloat foo [expr double(1)/41] + r incrbyfloat foo [expr double(-1)/41] + r get foo + } {0} } From ca5e8ac5b0eff61338e33676a5f10168ee3d2d98 Mon Sep 17 00:00:00 2001 From: Oran Agra Date: Tue, 10 Dec 2019 11:16:13 +0200 Subject: [PATCH 2/5] fix possible warning on incomplete struct init --- src/module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module.c b/src/module.c index 16d24152e..64f274e78 100644 --- a/src/module.c +++ b/src/module.c @@ -5978,7 +5978,7 @@ sds modulesCollectInfo(sds info, const char *section, int for_crash_report, int struct RedisModule *module = dictGetVal(de); if (!module->info_cb) continue; - RedisModuleInfoCtx info_ctx = {module, section, info, sections, 0}; + RedisModuleInfoCtx info_ctx = {module, section, info, sections, 0, 0}; module->info_cb(&info_ctx, for_crash_report); /* Implicitly end dicts (no way to handle errors, and we must add the newline). */ if (info_ctx.in_dict_field) From b4966a914f877f059a47fea1671a58ec43f83137 Mon Sep 17 00:00:00 2001 From: Oran Agra Date: Sun, 23 Feb 2020 16:51:27 +0200 Subject: [PATCH 3/5] change CI to build and run the module api tests --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cc4991606..3a81d1a08 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,8 @@ jobs: run: | sudo apt-get install tcl8.5 ./runtest --clients 2 --verbose + - name: module api test + run: ./runtest-moduleapi --clients 2 --verbose build-ubuntu-old: runs-on: ubuntu-16.04 From 6f5462907140167f2bf664efcf197c92edcb81a2 Mon Sep 17 00:00:00 2001 From: Oran Agra Date: Mon, 23 Dec 2019 10:15:52 +0200 Subject: [PATCH 4/5] modules don't signalModifiedKey in setKey() since that's done (optionally) in RM_CloseKey --- src/db.c | 6 +++--- src/module.c | 6 +++--- src/server.h | 2 +- src/t_string.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/db.c b/src/db.c index 211bb978d..cadfeb77b 100644 --- a/src/db.c +++ b/src/db.c @@ -221,7 +221,7 @@ void dbOverwrite(redisDb *db, robj *key, robj *val) { * unless 'keepttl' is true. * * All the new keys in the database should be created via this interface. */ -void genericSetKey(redisDb *db, robj *key, robj *val, int keepttl) { +void genericSetKey(redisDb *db, robj *key, robj *val, int keepttl, int signal) { if (lookupKeyWrite(db,key) == NULL) { dbAdd(db,key,val); } else { @@ -229,12 +229,12 @@ void genericSetKey(redisDb *db, robj *key, robj *val, int keepttl) { } incrRefCount(val); if (!keepttl) removeExpire(db,key); - signalModifiedKey(db,key); + if (signal) signalModifiedKey(db,key); } /* Common case for genericSetKey() where the TTL is not retained. */ void setKey(redisDb *db, robj *key, robj *val) { - genericSetKey(db,key,val,0); + genericSetKey(db,key,val,0,1); } /* Return true if the specified key exists in the specified database. diff --git a/src/module.c b/src/module.c index 64f274e78..4d3d9e1af 100644 --- a/src/module.c +++ b/src/module.c @@ -2157,7 +2157,7 @@ RedisModuleString *RM_RandomKey(RedisModuleCtx *ctx) { int RM_StringSet(RedisModuleKey *key, RedisModuleString *str) { if (!(key->mode & REDISMODULE_WRITE) || key->iter) return REDISMODULE_ERR; RM_DeleteKey(key); - setKey(key->db,key->key,str); + genericSetKey(key->db,key->key,str,0,0); key->value = str; return REDISMODULE_OK; } @@ -2237,7 +2237,7 @@ int RM_StringTruncate(RedisModuleKey *key, size_t newlen) { if (key->value == NULL) { /* Empty key: create it with the new size. */ robj *o = createObject(OBJ_STRING,sdsnewlen(NULL, newlen)); - setKey(key->db,key->key,o); + genericSetKey(key->db,key->key,o,0,0); key->value = o; decrRefCount(o); } else { @@ -3625,7 +3625,7 @@ int RM_ModuleTypeSetValue(RedisModuleKey *key, moduleType *mt, void *value) { if (!(key->mode & REDISMODULE_WRITE) || key->iter) return REDISMODULE_ERR; RM_DeleteKey(key); robj *o = createModuleObject(mt,value); - setKey(key->db,key->key,o); + genericSetKey(key->db,key->key,o,0,0); decrRefCount(o); key->value = o; return REDISMODULE_OK; diff --git a/src/server.h b/src/server.h index c4db4278e..dbd72281f 100644 --- a/src/server.h +++ b/src/server.h @@ -2057,7 +2057,7 @@ int objectSetLRUOrLFU(robj *val, long long lfu_freq, long long lru_idle, #define LOOKUP_NOTOUCH (1<<0) void dbAdd(redisDb *db, robj *key, robj *val); void dbOverwrite(redisDb *db, robj *key, robj *val); -void genericSetKey(redisDb *db, robj *key, robj *val, int keepttl); +void genericSetKey(redisDb *db, robj *key, robj *val, int keepttl, int signal); void setKey(redisDb *db, robj *key, robj *val); int dbExists(redisDb *db, robj *key); robj *dbRandomKey(redisDb *db); diff --git a/src/t_string.c b/src/t_string.c index 8ccd69eb9..3174e9ccd 100644 --- a/src/t_string.c +++ b/src/t_string.c @@ -84,7 +84,7 @@ void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire, addReply(c, abort_reply ? abort_reply : shared.null[c->resp]); return; } - genericSetKey(c->db,key,val,flags & OBJ_SET_KEEPTTL); + genericSetKey(c->db,key,val,flags & OBJ_SET_KEEPTTL,1); server.dirty++; if (expire) setExpire(c,c->db,key,mstime()+milliseconds); notifyKeyspaceEvent(NOTIFY_STRING,"set",key,c->db->id); From 7cb94fd6cc9e1ad106964171023457ae3ff0a40b Mon Sep 17 00:00:00 2001 From: Guy Benoish Date: Thu, 2 Apr 2020 18:41:29 +0300 Subject: [PATCH 5/5] Fix no-negative-zero test --- tests/unit/type/incr.tcl | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/type/incr.tcl b/tests/unit/type/incr.tcl index 63bf2e116..b7a135203 100644 --- a/tests/unit/type/incr.tcl +++ b/tests/unit/type/incr.tcl @@ -153,6 +153,7 @@ start_server {tags {"incr"}} { } {ERR*valid*} test {No negative zero} { + r del foo r incrbyfloat foo [expr double(1)/41] r incrbyfloat foo [expr double(-1)/41] r get foo