Skip to content

Commit

Permalink
Make sure error and status replies emitted by Lua scripts can never h…
Browse files Browse the repository at this point in the history
…ave more than a newline, otherwise it is a protocol violation and clients will desync.
  • Loading branch information
antirez committed Jun 14, 2011
1 parent a59e797 commit 112c444
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 4 deletions.
7 changes: 7 additions & 0 deletions src/networking.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,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);
}
Expand Down
12 changes: 8 additions & 4 deletions src/scripting.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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);
Expand Down
30 changes: 30 additions & 0 deletions src/sds.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,36 @@ sds *sdssplitargs(char *line, int *argc) {
return NULL;
}

void sdssplitargs_free(sds *argv, int argc) {
int j;

for (j = 0 ;j < argc; j++) sdsfree(argv[j]);
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 <stdio.h>
#include "testhelp.h"
Expand Down
2 changes: 2 additions & 0 deletions src/sds.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,7 @@ void sdstoupper(sds s);
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

0 comments on commit 112c444

Please sign in to comment.