Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
hiredis
Commits
6448f735
Unverified
Commit
6448f735
authored
Jun 07, 2020
by
Michael Grunder
Committed by
GitHub
Jun 07, 2020
Browse files
sdsrange overflow fix (#830)
Fix overflow bug in `sdsrange`
parent
c7267235
Changes
9
Hide whitespace changes
Inline
Side-by-side
hiredis.c
View file @
6448f735
...
...
@@ -920,17 +920,17 @@ int redisBufferWrite(redisContext *c, int *done) {
return
REDIS_ERR
;
if
(
sdslen
(
c
->
obuf
)
>
0
)
{
in
t
nwritten
=
c
->
funcs
->
write
(
c
);
ssize_
t
nwritten
=
c
->
funcs
->
write
(
c
);
if
(
nwritten
<
0
)
{
return
REDIS_ERR
;
}
else
if
(
nwritten
>
0
)
{
if
(
nwritten
==
(
s
igned
)
sdslen
(
c
->
obuf
))
{
if
(
nwritten
==
(
s
size_t
)
sdslen
(
c
->
obuf
))
{
sdsfree
(
c
->
obuf
);
c
->
obuf
=
sdsempty
();
if
(
c
->
obuf
==
NULL
)
goto
oom
;
}
else
{
sdsrange
(
c
->
obuf
,
nwritten
,
-
1
);
if
(
sdsrange
(
c
->
obuf
,
nwritten
,
-
1
)
<
0
)
goto
oom
;
}
}
}
...
...
hiredis.h
View file @
6448f735
...
...
@@ -39,6 +39,7 @@
#include <sys/time.h>
/* for struct timeval */
#else
struct
timeval
;
/* forward declaration */
typedef
long
long
ssize_t
;
#endif
#include <stdint.h>
/* uintXX_t, etc */
#include "sds.h"
/* for sds */
...
...
@@ -200,8 +201,8 @@ typedef struct redisContextFuncs {
void
(
*
free_privdata
)(
void
*
);
void
(
*
async_read
)(
struct
redisAsyncContext
*
);
void
(
*
async_write
)(
struct
redisAsyncContext
*
);
in
t
(
*
read
)(
struct
redisContext
*
,
char
*
,
size_t
);
in
t
(
*
write
)(
struct
redisContext
*
);
ssize_
t
(
*
read
)(
struct
redisContext
*
,
char
*
,
size_t
);
ssize_
t
(
*
write
)(
struct
redisContext
*
);
}
redisContextFuncs
;
/* Context for a connection to Redis */
...
...
net.c
View file @
6448f735
...
...
@@ -57,8 +57,8 @@ void redisNetClose(redisContext *c) {
}
}
in
t
redisNetRead
(
redisContext
*
c
,
char
*
buf
,
size_t
bufcap
)
{
in
t
nread
=
recv
(
c
->
fd
,
buf
,
bufcap
,
0
);
ssize_
t
redisNetRead
(
redisContext
*
c
,
char
*
buf
,
size_t
bufcap
)
{
ssize_
t
nread
=
recv
(
c
->
fd
,
buf
,
bufcap
,
0
);
if
(
nread
==
-
1
)
{
if
((
errno
==
EWOULDBLOCK
&&
!
(
c
->
flags
&
REDIS_BLOCK
))
||
(
errno
==
EINTR
))
{
/* Try again later */
...
...
@@ -79,8 +79,8 @@ int redisNetRead(redisContext *c, char *buf, size_t bufcap) {
}
}
in
t
redisNetWrite
(
redisContext
*
c
)
{
in
t
nwritten
=
send
(
c
->
fd
,
c
->
obuf
,
sdslen
(
c
->
obuf
),
0
);
ssize_
t
redisNetWrite
(
redisContext
*
c
)
{
ssize_
t
nwritten
=
send
(
c
->
fd
,
c
->
obuf
,
sdslen
(
c
->
obuf
),
0
);
if
(
nwritten
<
0
)
{
if
((
errno
==
EWOULDBLOCK
&&
!
(
c
->
flags
&
REDIS_BLOCK
))
||
(
errno
==
EINTR
))
{
/* Try again later */
...
...
net.h
View file @
6448f735
...
...
@@ -38,8 +38,8 @@
#include "hiredis.h"
void
redisNetClose
(
redisContext
*
c
);
in
t
redisNetRead
(
redisContext
*
c
,
char
*
buf
,
size_t
bufcap
);
in
t
redisNetWrite
(
redisContext
*
c
);
ssize_
t
redisNetRead
(
redisContext
*
c
,
char
*
buf
,
size_t
bufcap
);
ssize_
t
redisNetWrite
(
redisContext
*
c
);
int
redisCheckSocketError
(
redisContext
*
c
);
int
redisContextSetTimeout
(
redisContext
*
c
,
const
struct
timeval
tv
);
...
...
read.c
View file @
6448f735
...
...
@@ -720,7 +720,7 @@ int redisReaderGetReply(redisReader *r, void **reply) {
/* Discard part of the buffer when we've consumed at least 1k, to avoid
* doing unnecessary calls to memmove() in sds.c. */
if
(
r
->
pos
>=
1024
)
{
sdsrange
(
r
->
buf
,
r
->
pos
,
-
1
);
if
(
sdsrange
(
r
->
buf
,
r
->
pos
,
-
1
)
<
0
)
return
REDIS_ERR
;
r
->
pos
=
0
;
r
->
len
=
sdslen
(
r
->
buf
);
}
...
...
sds.c
View file @
6448f735
...
...
@@ -36,6 +36,7 @@
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <limits.h>
#include "sds.h"
#include "sdsalloc.h"
...
...
@@ -713,15 +714,20 @@ sds sdstrim(sds s, const char *cset) {
*
* The string is modified in-place.
*
* Return value:
* -1 (error) if sdslen(s) is larger than maximum positive ssize_t value.
* 0 on success.
*
* Example:
*
* s = sdsnew("Hello World");
* sdsrange(s,1,-1); => "ello World"
*/
void
sdsrange
(
sds
s
,
in
t
start
,
in
t
end
)
{
int
sdsrange
(
sds
s
,
ssize_
t
start
,
ssize_
t
end
)
{
size_t
newlen
,
len
=
sdslen
(
s
);
if
(
len
>
SSIZE_MAX
)
return
-
1
;
if
(
len
==
0
)
return
;
if
(
len
==
0
)
return
0
;
if
(
start
<
0
)
{
start
=
len
+
start
;
if
(
start
<
0
)
start
=
0
;
...
...
@@ -732,9 +738,9 @@ void sdsrange(sds s, int start, int end) {
}
newlen
=
(
start
>
end
)
?
0
:
(
end
-
start
)
+
1
;
if
(
newlen
!=
0
)
{
if
(
start
>=
(
s
igned
)
len
)
{
if
(
start
>=
(
s
size_t
)
len
)
{
newlen
=
0
;
}
else
if
(
end
>=
(
s
igned
)
len
)
{
}
else
if
(
end
>=
(
s
size_t
)
len
)
{
end
=
len
-
1
;
newlen
=
(
start
>
end
)
?
0
:
(
end
-
start
)
+
1
;
}
...
...
@@ -744,6 +750,7 @@ void sdsrange(sds s, int start, int end) {
if
(
start
&&
newlen
)
memmove
(
s
,
s
+
start
,
newlen
);
s
[
newlen
]
=
0
;
sdssetlen
(
s
,
newlen
);
return
0
;
}
/* Apply tolower() to every character of the sds string 's'. */
...
...
sds.h
View file @
6448f735
...
...
@@ -36,6 +36,8 @@
#define SDS_MAX_PREALLOC (1024*1024)
#ifdef _MSC_VER
#define __attribute__(x)
typedef
long
long
ssize_t
;
#define SSIZE_MAX (LLONG_MAX >> 1)
#endif
#include <sys/types.h>
...
...
@@ -239,7 +241,7 @@ sds sdscatprintf(sds s, const char *fmt, ...);
sds
sdscatfmt
(
sds
s
,
char
const
*
fmt
,
...);
sds
sdstrim
(
sds
s
,
const
char
*
cset
);
void
sdsrange
(
sds
s
,
in
t
start
,
in
t
end
);
int
sdsrange
(
sds
s
,
ssize_
t
start
,
ssize_
t
end
);
void
sdsupdatelen
(
sds
s
);
void
sdsclear
(
sds
s
);
int
sdscmp
(
const
sds
s1
,
const
sds
s2
);
...
...
sockcompat.h
View file @
6448f735
...
...
@@ -51,7 +51,7 @@
#include <stddef.h>
#ifdef _MSC_VER
typedef
signed
long
ssize_t
;
typedef
long
long
ssize_t
;
#endif
/* Emulate the parts of the BSD socket API that we need (override the winsock signatures). */
...
...
ssl.c
View file @
6448f735
...
...
@@ -392,7 +392,7 @@ static void redisSSLFree(void *privdata){
hi_free
(
rsc
);
}
static
in
t
redisSSLRead
(
redisContext
*
c
,
char
*
buf
,
size_t
bufcap
)
{
static
ssize_
t
redisSSLRead
(
redisContext
*
c
,
char
*
buf
,
size_t
bufcap
)
{
redisSSL
*
rssl
=
c
->
privdata
;
int
nread
=
SSL_read
(
rssl
->
ssl
,
buf
,
bufcap
);
...
...
@@ -434,7 +434,7 @@ static int redisSSLRead(redisContext *c, char *buf, size_t bufcap) {
}
}
static
in
t
redisSSLWrite
(
redisContext
*
c
)
{
static
ssize_
t
redisSSLWrite
(
redisContext
*
c
)
{
redisSSL
*
rssl
=
c
->
privdata
;
size_t
len
=
rssl
->
lastLen
?
rssl
->
lastLen
:
sdslen
(
c
->
obuf
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment