Permalink
Browse files

Make sure error and status replies emitted by Lua scripts can never h…

…ave more than a newline, otherwise it is a protocol violation and clients will desync.
  • Loading branch information...
1 parent a59e797 commit 112c4442a2ad1473f84fb4d740da9af5d22593e0 @antirez committed May 24, 2011
Showing with 47 additions and 4 deletions.
  1. +7 −0 src/networking.c
  2. +8 −4 src/scripting.c
  3. +30 −0 src/sds.c
  4. +2 −0 src/sds.h
View
@@ -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);
}
View
@@ -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);
View
@@ -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"
View
@@ -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.