summaryrefslogtreecommitdiff
path: root/hiredis.c
diff options
context:
space:
mode:
Diffstat (limited to 'hiredis.c')
-rw-r--r--hiredis.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/hiredis.c b/hiredis.c
index 6db1075..5f56bf7 100644
--- a/hiredis.c
+++ b/hiredis.c
@@ -192,6 +192,35 @@ static char *seekNewline(char *s, size_t len) {
return NULL;
}
+/* Read a long long value starting at *s, under the assumption that it will be
+ * terminated by \r\n. Ambiguously returns -1 for unexpected input. */
+static long long readLongLong(char *s) {
+ long long v = 0;
+ int dec, mult = 1;
+ char c;
+
+ if (*s == '-') {
+ mult = -1;
+ s++;
+ } else if (*s == '+') {
+ mult = 1;
+ s++;
+ }
+
+ while ((c = *(s++)) != '\r') {
+ dec = c - '0';
+ if (dec >= 0 && dec < 10) {
+ v *= 10;
+ v += dec;
+ } else {
+ /* Should not happen... */
+ return -1;
+ }
+ }
+
+ return mult*v;
+}
+
static char *readLine(redisReader *r, int *_len) {
char *p, *s;
int len;
@@ -241,7 +270,7 @@ static int processLineItem(redisReader *r) {
if ((p = readLine(r,&len)) != NULL) {
if (r->fn) {
if (cur->type == REDIS_REPLY_INTEGER) {
- obj = r->fn->createInteger(cur,strtoll(p,NULL,10));
+ obj = r->fn->createInteger(cur,readLongLong(p));
} else {
obj = r->fn->createString(cur,p,len);
}
@@ -270,7 +299,7 @@ static int processBulkItem(redisReader *r) {
if (s != NULL) {
p = r->buf+r->pos;
bytelen = s-(r->buf+r->pos)+2; /* include \r\n */
- len = strtol(p,NULL,10);
+ len = readLongLong(p);
if (len < 0) {
/* The nil object can always be created. */
@@ -315,7 +344,7 @@ static int processMultiBulkItem(redisReader *r) {
}
if ((p = readLine(r,NULL)) != NULL) {
- elements = strtol(p,NULL,10);
+ elements = readLongLong(p);
root = (r->ridx == 0);
if (elements == -1) {