diff --git a/src/networking.c b/src/networking.c index 976b472a197033b8adf8be370ba9f67f9aee2766..e88e27d1640949f8bda71b2a91af3243ab33a62e 100644 --- a/src/networking.c +++ b/src/networking.c @@ -246,10 +246,17 @@ void addReplyError(redisClient *c, char *err) { } void addReplyErrorFormat(redisClient *c, const char *fmt, ...) { + size_t l, j; va_list ap; va_start(ap,fmt); sds s = sdscatvprintf(sdsempty(),fmt,ap); va_end(ap); + /* Make sure there are no newlines in the string, otherwise invalid protocol + * is emitted. */ + l = sdslen(s); + for (j = 0; j < l; j++) { + if (s[j] == '\r' || s[j] == '\n') s[j] = ' '; + } _addReplyError(c,s,sdslen(s)); sdsfree(s); } diff --git a/src/scripting.c b/src/scripting.c index be6247a907d984a2a5b79ccdc30807e0098430dd..469d78708caf9cef1824632fbb067c856911dd8c 100644 --- a/src/scripting.c +++ b/src/scripting.c @@ -332,8 +332,10 @@ void luaReplyToRedisReply(redisClient *c, lua_State *lua) { lua_gettable(lua,-2); t = lua_type(lua,-1); if (t == LUA_TSTRING) { - addReplySds(c,sdscatprintf(sdsempty(), - "-%s\r\n",(char*)lua_tostring(lua,-1))); + sds err = sdsnew(lua_tostring(lua,-1)); + sdsmapchars(err,"\r\n"," ",2); + addReplySds(c,sdscatprintf(sdsempty(),"-%s\r\n",err)); + sdsfree(err); lua_pop(lua,2); return; } @@ -343,8 +345,10 @@ void luaReplyToRedisReply(redisClient *c, lua_State *lua) { lua_gettable(lua,-2); t = lua_type(lua,-1); if (t == LUA_TSTRING) { - addReplySds(c,sdscatprintf(sdsempty(), - "+%s\r\n",(char*)lua_tostring(lua,-1))); + sds ok = sdsnew(lua_tostring(lua,-1)); + sdsmapchars(ok,"\r\n"," ",2); + addReplySds(c,sdscatprintf(sdsempty(),"+%s\r\n",ok)); + sdsfree(ok); lua_pop(lua,1); } else { void *replylen = addDeferredMultiBulkLength(c); diff --git a/src/sds.c b/src/sds.c index 63507000b106e6fefc8a8d099f1f68d9f846afe9..2ec7c3cb76b3a2d6f5afdb3be8bd6aa793329a1c 100644 --- a/src/sds.c +++ b/src/sds.c @@ -553,6 +553,29 @@ void sdssplitargs_free(sds *argv, int argc) { zfree(argv); } +/* Modify the string substituting all the occurrences of the set of + * characters specifed in the 'from' string to the corresponding character + * in the 'to' array. + * + * For instance: sdsmapchars(mystring, "ho", "01", 2) + * will have the effect of turning the string "hello" into "0ell1". + * + * The function returns the sds string pointer, that is always the same + * as the input pointer since no resize is needed. */ +sds sdsmapchars(sds s, char *from, char *to, size_t setlen) { + size_t j, i, l = sdslen(s); + + for (j = 0; j < l; j++) { + for (i = 0; i < setlen; i++) { + if (s[j] == from[i]) { + s[j] = to[i]; + break; + } + } + } + return s; +} + #ifdef SDS_TEST_MAIN #include #include "testhelp.h" diff --git a/src/sds.h b/src/sds.h index ea43f868265e1b01aeb92b78c3fc2d0b8b33b47b..af5c4910bdae766730c776691fdd2019d18d920c 100644 --- a/src/sds.h +++ b/src/sds.h @@ -85,5 +85,6 @@ sds sdsfromlonglong(long long value); sds sdscatrepr(sds s, char *p, size_t len); sds *sdssplitargs(char *line, int *argc); void sdssplitargs_free(sds *argv, int argc); +sds sdsmapchars(sds s, char *from, char *to, size_t setlen); #endif