summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/config.c13
-rw-r--r--src/util.c23
2 files changed, 25 insertions, 11 deletions
diff --git a/src/config.c b/src/config.c
index 8255a56b7..3963a1218 100644
--- a/src/config.c
+++ b/src/config.c
@@ -624,6 +624,7 @@ void loadServerConfig(char *filename, char *options) {
void configSetCommand(redisClient *c) {
robj *o;
long long ll;
+ int err;
redisAssertWithInfo(c,c->argv[2],sdsEncodedObject(c->argv[2]));
redisAssertWithInfo(c,c->argv[3],sdsEncodedObject(c->argv[3]));
o = c->argv[3];
@@ -643,8 +644,8 @@ void configSetCommand(redisClient *c) {
zfree(server.masterauth);
server.masterauth = ((char*)o->ptr)[0] ? zstrdup(o->ptr) : NULL;
} else if (!strcasecmp(c->argv[2]->ptr,"maxmemory")) {
- if (getLongLongFromObject(o,&ll) == REDIS_ERR ||
- ll < 0) goto badfmt;
+ ll = memtoll(o->ptr,&err);
+ if (err || ll < 0) goto badfmt;
server.maxmemory = ll;
if (server.maxmemory) {
if (server.maxmemory < zmalloc_used_memory()) {
@@ -866,7 +867,6 @@ void configSetCommand(redisClient *c) {
* whole configuration string or accept it all, even if a single
* error in a single client class is present. */
for (j = 0; j < vlen; j++) {
- char *eptr;
long val;
if ((j % 4) == 0) {
@@ -875,8 +875,8 @@ void configSetCommand(redisClient *c) {
goto badfmt;
}
} else {
- val = strtoll(v[j], &eptr, 10);
- if (eptr[0] != '\0' || val < 0) {
+ val = memtoll(v[j], &err);
+ if (err || val < 0) {
sdsfreesplitres(v,vlen);
goto badfmt;
}
@@ -910,7 +910,8 @@ void configSetCommand(redisClient *c) {
if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll <= 0) goto badfmt;
server.repl_timeout = ll;
} else if (!strcasecmp(c->argv[2]->ptr,"repl-backlog-size")) {
- if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll <= 0) goto badfmt;
+ ll = memtoll(o->ptr,&err);
+ if (err || ll < 0) goto badfmt;
resizeReplicationBacklog(ll);
} else if (!strcasecmp(c->argv[2]->ptr,"repl-backlog-ttl")) {
if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0) goto badfmt;
diff --git a/src/util.c b/src/util.c
index 543de112b..4190775b1 100644
--- a/src/util.c
+++ b/src/util.c
@@ -38,6 +38,7 @@
#include <sys/time.h>
#include <float.h>
#include <stdint.h>
+#include <errno.h>
#include "util.h"
#include "sha1.h"
@@ -170,11 +171,12 @@ int stringmatch(const char *pattern, const char *string, int nocase) {
}
/* Convert a string representing an amount of memory into the number of
- * bytes, so for instance memtoll("1Gi") will return 1073741824 that is
+ * bytes, so for instance memtoll("1Gb") will return 1073741824 that is
* (1024*1024*1024).
*
* On parsing error, if *err is not NULL, it's set to 1, otherwise it's
- * set to 0 */
+ * set to 0. On error the function return value is 0, regardless of the
+ * fact 'err' is NULL or not. */
long long memtoll(const char *p, int *err) {
const char *u;
char buf[128];
@@ -183,6 +185,7 @@ long long memtoll(const char *p, int *err) {
unsigned int digits;
if (err) *err = 0;
+
/* Search the first non digit character. */
u = p;
if (*u == '-') u++;
@@ -203,16 +206,26 @@ long long memtoll(const char *p, int *err) {
mul = 1024L*1024*1024;
} else {
if (err) *err = 1;
- mul = 1;
+ return 0;
}
+
+ /* Copy the digits into a buffer, we'll use strtoll() to convert
+ * the digit (without the unit) into a number. */
digits = u-p;
if (digits >= sizeof(buf)) {
if (err) *err = 1;
- return LLONG_MAX;
+ return 0;
}
memcpy(buf,p,digits);
buf[digits] = '\0';
- val = strtoll(buf,NULL,10);
+
+ char *endptr;
+ errno = 0;
+ val = strtoll(buf,&endptr,10);
+ if ((val == 0 && errno == EINVAL) || *endptr != '\0') {
+ if (err) *err = 1;
+ return 0;
+ }
return val*mul;
}