Unverified Commit f2be7480 authored by sundb's avatar sundb Committed by GitHub
Browse files

Fix integer overflow when format command larger than 4GB (#1030)

parent 58aacdac
...@@ -862,7 +862,7 @@ int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata ...@@ -862,7 +862,7 @@ int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata
int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen) { int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen) {
sds cmd; sds cmd;
int len; long long len;
int status; int status;
len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen); len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen);
if (len < 0) if (len < 0)
......
...@@ -572,13 +572,12 @@ int redisFormatCommand(char **target, const char *format, ...) { ...@@ -572,13 +572,12 @@ int redisFormatCommand(char **target, const char *format, ...) {
* lengths. If the latter is set to NULL, strlen will be used to compute the * lengths. If the latter is set to NULL, strlen will be used to compute the
* argument lengths. * argument lengths.
*/ */
int redisFormatSdsCommandArgv(sds *target, int argc, const char **argv, long long redisFormatSdsCommandArgv(sds *target, int argc, const char **argv,
const size_t *argvlen) const size_t *argvlen)
{ {
sds cmd, aux; sds cmd, aux;
unsigned long long totlen; unsigned long long totlen, len;
int j; int j;
size_t len;
/* Abort on a NULL target */ /* Abort on a NULL target */
if (target == NULL) if (target == NULL)
...@@ -609,7 +608,7 @@ int redisFormatSdsCommandArgv(sds *target, int argc, const char **argv, ...@@ -609,7 +608,7 @@ int redisFormatSdsCommandArgv(sds *target, int argc, const char **argv,
cmd = sdscatfmt(cmd, "*%i\r\n", argc); cmd = sdscatfmt(cmd, "*%i\r\n", argc);
for (j=0; j < argc; j++) { for (j=0; j < argc; j++) {
len = argvlen ? argvlen[j] : strlen(argv[j]); len = argvlen ? argvlen[j] : strlen(argv[j]);
cmd = sdscatfmt(cmd, "$%u\r\n", len); cmd = sdscatfmt(cmd, "$%U\r\n", len);
cmd = sdscatlen(cmd, argv[j], len); cmd = sdscatlen(cmd, argv[j], len);
cmd = sdscatlen(cmd, "\r\n", sizeof("\r\n")-1); cmd = sdscatlen(cmd, "\r\n", sizeof("\r\n")-1);
} }
...@@ -629,11 +628,11 @@ void redisFreeSdsCommand(sds cmd) { ...@@ -629,11 +628,11 @@ void redisFreeSdsCommand(sds cmd) {
* lengths. If the latter is set to NULL, strlen will be used to compute the * lengths. If the latter is set to NULL, strlen will be used to compute the
* argument lengths. * argument lengths.
*/ */
int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) { long long redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) {
char *cmd = NULL; /* final command */ char *cmd = NULL; /* final command */
int pos; /* position in final command */ size_t pos; /* position in final command */
size_t len; size_t len, totlen;
int totlen, j; int j;
/* Abort on a NULL target */ /* Abort on a NULL target */
if (target == NULL) if (target == NULL)
...@@ -1129,7 +1128,7 @@ int redisAppendCommand(redisContext *c, const char *format, ...) { ...@@ -1129,7 +1128,7 @@ int redisAppendCommand(redisContext *c, const char *format, ...) {
int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) { int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) {
sds cmd; sds cmd;
int len; long long len;
len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen); len = redisFormatSdsCommandArgv(&cmd,argc,argv,argvlen);
if (len == -1) { if (len == -1) {
......
...@@ -134,8 +134,8 @@ void freeReplyObject(void *reply); ...@@ -134,8 +134,8 @@ void freeReplyObject(void *reply);
/* Functions to format a command according to the protocol. */ /* Functions to format a command according to the protocol. */
int redisvFormatCommand(char **target, const char *format, va_list ap); int redisvFormatCommand(char **target, const char *format, va_list ap);
int redisFormatCommand(char **target, const char *format, ...); int redisFormatCommand(char **target, const char *format, ...);
int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen); long long redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen);
int redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen); long long redisFormatSdsCommandArgv(sds *target, int argc, const char ** argv, const size_t *argvlen);
void redisFreeCommand(char *cmd); void redisFreeCommand(char *cmd);
void redisFreeSdsCommand(sds cmd); void redisFreeSdsCommand(sds cmd);
......
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