mirror of
https://github.com/phpredis/phpredis.git
synced 2026-06-19 07:35:31 +00:00
library: replace atol with bounded strtoll for RESP length parsing
atol returns undefined behavior on overflow per C11 7.22.1.4. glibc saturates to LONG_MAX, but musl, BSD libc, and Windows libc differ. Replace atol / atoi at the three RESP length parse sites in library.c with strtoll plus ERANGE rejection. The wire input is server- controlled; an out-of-range value should drop the reply rather than land an implementation-defined value in downstream length arithmetic.
This commit is contained in:
committed by
Michael Grunder
parent
b112875b70
commit
5c6e2d2b3c
@@ -7,6 +7,8 @@
|
||||
#include "common.h"
|
||||
#include "php_network.h"
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef HAVE_REDIS_IGBINARY
|
||||
#include "igbinary/igbinary.h"
|
||||
@@ -364,7 +366,17 @@ read_mbulk_header(RedisSock *redis_sock, int *nelem)
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
*nelem = atoi(line + 1);
|
||||
{
|
||||
char *endptr;
|
||||
long long n;
|
||||
|
||||
errno = 0;
|
||||
n = strtoll(line + 1, &endptr, 10);
|
||||
if (endptr == line + 1 || errno == ERANGE || n < -1 || n > INT_MAX) {
|
||||
return FAILURE;
|
||||
}
|
||||
*nelem = (int)n;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -822,7 +834,17 @@ redis_sock_read(RedisSock *redis_sock, int *buf_len)
|
||||
|
||||
return NULL;
|
||||
case '$':
|
||||
*buf_len = atoi(inbuf + 1);
|
||||
{
|
||||
char *endptr;
|
||||
long long n;
|
||||
|
||||
errno = 0;
|
||||
n = strtoll(inbuf + 1, &endptr, 10);
|
||||
if (endptr == inbuf + 1 || errno == ERANGE || n < -1 || n > INT_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
*buf_len = (int)n;
|
||||
}
|
||||
return redis_sock_read_bulk_reply(redis_sock, *buf_len);
|
||||
|
||||
case '*':
|
||||
@@ -4567,7 +4589,15 @@ redis_read_reply_type(RedisSock *redis_sock, REDIS_REPLY_TYPE *reply_type,
|
||||
}
|
||||
|
||||
/* Set our size response */
|
||||
*reply_info = atol(inbuf);
|
||||
{
|
||||
char *endptr;
|
||||
|
||||
errno = 0;
|
||||
*reply_info = strtol(inbuf, &endptr, 10);
|
||||
if (endptr == inbuf || errno == ERANGE) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Always initialize to prevent UB */
|
||||
*reply_info = 0;
|
||||
|
||||
Reference in New Issue
Block a user