Commit 3bb818df authored by antirez's avatar antirez
Browse files

Make sure error and status replies emitted by Lua scripts can never have more...

Make sure error and status replies emitted by Lua scripts can never have more than a newline, otherwise it is a protocol violation and clients will desync.
parent 449286a5
...@@ -246,10 +246,17 @@ void addReplyError(redisClient *c, char *err) { ...@@ -246,10 +246,17 @@ void addReplyError(redisClient *c, char *err) {
} }
void addReplyErrorFormat(redisClient *c, const char *fmt, ...) { void addReplyErrorFormat(redisClient *c, const char *fmt, ...) {
size_t l, j;
va_list ap; va_list ap;
va_start(ap,fmt); va_start(ap,fmt);
sds s = sdscatvprintf(sdsempty(),fmt,ap); sds s = sdscatvprintf(sdsempty(),fmt,ap);
va_end(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)); _addReplyError(c,s,sdslen(s));
sdsfree(s); sdsfree(s);
} }
......
...@@ -332,8 +332,10 @@ void luaReplyToRedisReply(redisClient *c, lua_State *lua) { ...@@ -332,8 +332,10 @@ void luaReplyToRedisReply(redisClient *c, lua_State *lua) {
lua_gettable(lua,-2); lua_gettable(lua,-2);
t = lua_type(lua,-1); t = lua_type(lua,-1);
if (t == LUA_TSTRING) { if (t == LUA_TSTRING) {
addReplySds(c,sdscatprintf(sdsempty(), sds err = sdsnew(lua_tostring(lua,-1));
"-%s\r\n",(char*)lua_tostring(lua,-1))); sdsmapchars(err,"\r\n"," ",2);
addReplySds(c,sdscatprintf(sdsempty(),"-%s\r\n",err));
sdsfree(err);
lua_pop(lua,2); lua_pop(lua,2);
return; return;
} }
...@@ -343,8 +345,10 @@ void luaReplyToRedisReply(redisClient *c, lua_State *lua) { ...@@ -343,8 +345,10 @@ void luaReplyToRedisReply(redisClient *c, lua_State *lua) {
lua_gettable(lua,-2); lua_gettable(lua,-2);
t = lua_type(lua,-1); t = lua_type(lua,-1);
if (t == LUA_TSTRING) { if (t == LUA_TSTRING) {
addReplySds(c,sdscatprintf(sdsempty(), sds ok = sdsnew(lua_tostring(lua,-1));
"+%s\r\n",(char*)lua_tostring(lua,-1))); sdsmapchars(ok,"\r\n"," ",2);
addReplySds(c,sdscatprintf(sdsempty(),"+%s\r\n",ok));
sdsfree(ok);
lua_pop(lua,1); lua_pop(lua,1);
} else { } else {
void *replylen = addDeferredMultiBulkLength(c); void *replylen = addDeferredMultiBulkLength(c);
......
...@@ -553,6 +553,29 @@ void sdssplitargs_free(sds *argv, int argc) { ...@@ -553,6 +553,29 @@ void sdssplitargs_free(sds *argv, int argc) {
zfree(argv); 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 #ifdef SDS_TEST_MAIN
#include <stdio.h> #include <stdio.h>
#include "testhelp.h" #include "testhelp.h"
......
...@@ -85,5 +85,6 @@ sds sdsfromlonglong(long long value); ...@@ -85,5 +85,6 @@ sds sdsfromlonglong(long long value);
sds sdscatrepr(sds s, char *p, size_t len); sds sdscatrepr(sds s, char *p, size_t len);
sds *sdssplitargs(char *line, int *argc); sds *sdssplitargs(char *line, int *argc);
void sdssplitargs_free(sds *argv, int argc); void sdssplitargs_free(sds *argv, int argc);
sds sdsmapchars(sds s, char *from, char *to, size_t setlen);
#endif #endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment