From 29b54db32091fb04a75a9dc196adc492e4933493 Mon Sep 17 00:00:00 2001 From: antirez Date: Thu, 12 Feb 2015 16:40:41 +0100 Subject: Better memtoll() error checking. Related to PR #2357. --- src/util.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) 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 #include #include +#include #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; } -- cgit v1.2.1