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
redis
Commits
819d291b
Commit
819d291b
authored
Jul 10, 2023
by
Oran Agra
Browse files
Merge remote-tracking branch 'origin/unstable' into 7.2
parents
a51eb05b
936cfa46
Changes
151
Hide whitespace changes
Inline
Side-by-side
deps/hiredis/examples/example-libevent-ssl.c
View file @
819d291b
...
...
@@ -56,7 +56,7 @@ int main (int argc, char **argv) {
const
char
*
caCert
=
argc
>
5
?
argv
[
6
]
:
NULL
;
redisSSLContext
*
ssl
;
redisSSLContextError
ssl_error
;
redisSSLContextError
ssl_error
=
REDIS_SSL_CTX_NONE
;
redisInitOpenSSL
();
...
...
deps/hiredis/examples/example-libhv.c
0 → 100644
View file @
819d291b
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <hiredis.h>
#include <async.h>
#include <adapters/libhv.h>
void
getCallback
(
redisAsyncContext
*
c
,
void
*
r
,
void
*
privdata
)
{
redisReply
*
reply
=
r
;
if
(
reply
==
NULL
)
return
;
printf
(
"argv[%s]: %s
\n
"
,
(
char
*
)
privdata
,
reply
->
str
);
/* Disconnect after receiving the reply to GET */
redisAsyncDisconnect
(
c
);
}
void
debugCallback
(
redisAsyncContext
*
c
,
void
*
r
,
void
*
privdata
)
{
(
void
)
privdata
;
redisReply
*
reply
=
r
;
if
(
reply
==
NULL
)
{
printf
(
"`DEBUG SLEEP` error: %s
\n
"
,
c
->
errstr
?
c
->
errstr
:
"unknown error"
);
return
;
}
redisAsyncDisconnect
(
c
);
}
void
connectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
if
(
status
!=
REDIS_OK
)
{
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
return
;
}
printf
(
"Connected...
\n
"
);
}
void
disconnectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
if
(
status
!=
REDIS_OK
)
{
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
return
;
}
printf
(
"Disconnected...
\n
"
);
}
int
main
(
int
argc
,
char
**
argv
)
{
#ifndef _WIN32
signal
(
SIGPIPE
,
SIG_IGN
);
#endif
redisAsyncContext
*
c
=
redisAsyncConnect
(
"127.0.0.1"
,
6379
);
if
(
c
->
err
)
{
/* Let *c leak for now... */
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
return
1
;
}
hloop_t
*
loop
=
hloop_new
(
HLOOP_FLAG_QUIT_WHEN_NO_ACTIVE_EVENTS
);
redisLibhvAttach
(
c
,
loop
);
redisAsyncSetTimeout
(
c
,
(
struct
timeval
){.
tv_sec
=
0
,
.
tv_usec
=
500000
});
redisAsyncSetConnectCallback
(
c
,
connectCallback
);
redisAsyncSetDisconnectCallback
(
c
,
disconnectCallback
);
redisAsyncCommand
(
c
,
NULL
,
NULL
,
"SET key %b"
,
argv
[
argc
-
1
],
strlen
(
argv
[
argc
-
1
]));
redisAsyncCommand
(
c
,
getCallback
,
(
char
*
)
"end-1"
,
"GET key"
);
redisAsyncCommand
(
c
,
debugCallback
,
NULL
,
"DEBUG SLEEP %d"
,
1
);
hloop_run
(
loop
);
hloop_free
(
&
loop
);
return
0
;
}
deps/hiredis/examples/example-libsdevent.c
0 → 100644
View file @
819d291b
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <hiredis.h>
#include <async.h>
#include <adapters/libsdevent.h>
void
debugCallback
(
redisAsyncContext
*
c
,
void
*
r
,
void
*
privdata
)
{
(
void
)
privdata
;
redisReply
*
reply
=
r
;
if
(
reply
==
NULL
)
{
/* The DEBUG SLEEP command will almost always fail, because we have set a 1 second timeout */
printf
(
"`DEBUG SLEEP` error: %s
\n
"
,
c
->
errstr
?
c
->
errstr
:
"unknown error"
);
return
;
}
/* Disconnect after receiving the reply of DEBUG SLEEP (which will not)*/
redisAsyncDisconnect
(
c
);
}
void
getCallback
(
redisAsyncContext
*
c
,
void
*
r
,
void
*
privdata
)
{
redisReply
*
reply
=
r
;
if
(
reply
==
NULL
)
{
printf
(
"`GET key` error: %s
\n
"
,
c
->
errstr
?
c
->
errstr
:
"unknown error"
);
return
;
}
printf
(
"`GET key` result: argv[%s]: %s
\n
"
,
(
char
*
)
privdata
,
reply
->
str
);
/* start another request that demonstrate timeout */
redisAsyncCommand
(
c
,
debugCallback
,
NULL
,
"DEBUG SLEEP %f"
,
1
.
5
);
}
void
connectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
if
(
status
!=
REDIS_OK
)
{
printf
(
"connect error: %s
\n
"
,
c
->
errstr
);
return
;
}
printf
(
"Connected...
\n
"
);
}
void
disconnectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
if
(
status
!=
REDIS_OK
)
{
printf
(
"disconnect because of error: %s
\n
"
,
c
->
errstr
);
return
;
}
printf
(
"Disconnected...
\n
"
);
}
int
main
(
int
argc
,
char
**
argv
)
{
signal
(
SIGPIPE
,
SIG_IGN
);
struct
sd_event
*
event
;
sd_event_default
(
&
event
);
redisAsyncContext
*
c
=
redisAsyncConnect
(
"127.0.0.1"
,
6379
);
if
(
c
->
err
)
{
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
redisAsyncFree
(
c
);
return
1
;
}
redisLibsdeventAttach
(
c
,
event
);
redisAsyncSetConnectCallback
(
c
,
connectCallback
);
redisAsyncSetDisconnectCallback
(
c
,
disconnectCallback
);
redisAsyncSetTimeout
(
c
,
(
struct
timeval
){
.
tv_sec
=
1
,
.
tv_usec
=
0
});
/*
In this demo, we first `set key`, then `get key` to demonstrate the basic usage of libsdevent adapter.
Then in `getCallback`, we start a `debug sleep` command to create 1.5 second long request.
Because we have set a 1 second timeout to the connection, the command will always fail with a
timeout error, which is shown in the `debugCallback`.
*/
redisAsyncCommand
(
c
,
NULL
,
NULL
,
"SET key %b"
,
argv
[
argc
-
1
],
strlen
(
argv
[
argc
-
1
]));
redisAsyncCommand
(
c
,
getCallback
,
(
char
*
)
"end-1"
,
"GET key"
);
/* sd-event does not quit when there are no handlers registered. Manually exit after 1.5 seconds */
sd_event_source
*
s
;
sd_event_add_time_relative
(
event
,
&
s
,
CLOCK_MONOTONIC
,
1500000
,
1
,
NULL
,
NULL
);
sd_event_loop
(
event
);
sd_event_source_disable_unref
(
s
);
sd_event_unref
(
event
);
return
0
;
}
deps/hiredis/examples/example-poll.c
0 → 100644
View file @
819d291b
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <async.h>
#include <adapters/poll.h>
/* Put in the global scope, so that loop can be explicitly stopped */
static
int
exit_loop
=
0
;
void
getCallback
(
redisAsyncContext
*
c
,
void
*
r
,
void
*
privdata
)
{
redisReply
*
reply
=
r
;
if
(
reply
==
NULL
)
return
;
printf
(
"argv[%s]: %s
\n
"
,
(
char
*
)
privdata
,
reply
->
str
);
/* Disconnect after receiving the reply to GET */
redisAsyncDisconnect
(
c
);
}
void
connectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
if
(
status
!=
REDIS_OK
)
{
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
exit_loop
=
1
;
return
;
}
printf
(
"Connected...
\n
"
);
}
void
disconnectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
exit_loop
=
1
;
if
(
status
!=
REDIS_OK
)
{
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
return
;
}
printf
(
"Disconnected...
\n
"
);
}
int
main
(
int
argc
,
char
**
argv
)
{
signal
(
SIGPIPE
,
SIG_IGN
);
redisAsyncContext
*
c
=
redisAsyncConnect
(
"127.0.0.1"
,
6379
);
if
(
c
->
err
)
{
/* Let *c leak for now... */
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
return
1
;
}
redisPollAttach
(
c
);
redisAsyncSetConnectCallback
(
c
,
connectCallback
);
redisAsyncSetDisconnectCallback
(
c
,
disconnectCallback
);
redisAsyncCommand
(
c
,
NULL
,
NULL
,
"SET key %b"
,
argv
[
argc
-
1
],
strlen
(
argv
[
argc
-
1
]));
redisAsyncCommand
(
c
,
getCallback
,
(
char
*
)
"end-1"
,
"GET key"
);
while
(
!
exit_loop
)
{
redisPollTick
(
c
,
0
.
1
);
}
return
0
;
}
deps/hiredis/examples/example-redismoduleapi.c
0 → 100644
View file @
819d291b
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <hiredis.h>
#include <async.h>
#include <adapters/redismoduleapi.h>
void
debugCallback
(
redisAsyncContext
*
c
,
void
*
r
,
void
*
privdata
)
{
(
void
)
privdata
;
//unused
redisReply
*
reply
=
r
;
if
(
reply
==
NULL
)
{
/* The DEBUG SLEEP command will almost always fail, because we have set a 1 second timeout */
printf
(
"`DEBUG SLEEP` error: %s
\n
"
,
c
->
errstr
?
c
->
errstr
:
"unknown error"
);
return
;
}
/* Disconnect after receiving the reply of DEBUG SLEEP (which will not)*/
redisAsyncDisconnect
(
c
);
}
void
getCallback
(
redisAsyncContext
*
c
,
void
*
r
,
void
*
privdata
)
{
redisReply
*
reply
=
r
;
if
(
reply
==
NULL
)
{
if
(
c
->
errstr
)
{
printf
(
"errstr: %s
\n
"
,
c
->
errstr
);
}
return
;
}
printf
(
"argv[%s]: %s
\n
"
,
(
char
*
)
privdata
,
reply
->
str
);
/* start another request that demonstrate timeout */
redisAsyncCommand
(
c
,
debugCallback
,
NULL
,
"DEBUG SLEEP %f"
,
1
.
5
);
}
void
connectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
if
(
status
!=
REDIS_OK
)
{
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
return
;
}
printf
(
"Connected...
\n
"
);
}
void
disconnectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
if
(
status
!=
REDIS_OK
)
{
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
return
;
}
printf
(
"Disconnected...
\n
"
);
}
/*
* This example requires Redis 7.0 or above.
*
* 1- Compile this file as a shared library. Directory of "redismodule.h" must
* be in the include path.
* gcc -fPIC -shared -I../../redis/src/ -I.. example-redismoduleapi.c -o example-redismoduleapi.so
*
* 2- Load module:
* redis-server --loadmodule ./example-redismoduleapi.so value
*/
int
RedisModule_OnLoad
(
RedisModuleCtx
*
ctx
,
RedisModuleString
**
argv
,
int
argc
)
{
int
ret
=
RedisModule_Init
(
ctx
,
"example-redismoduleapi"
,
1
,
REDISMODULE_APIVER_1
);
if
(
ret
!=
REDISMODULE_OK
)
{
printf
(
"error module init
\n
"
);
return
REDISMODULE_ERR
;
}
if
(
redisModuleCompatibilityCheck
()
!=
REDIS_OK
)
{
printf
(
"Redis 7.0 or above is required!
\n
"
);
return
REDISMODULE_ERR
;
}
redisAsyncContext
*
c
=
redisAsyncConnect
(
"127.0.0.1"
,
6379
);
if
(
c
->
err
)
{
/* Let *c leak for now... */
printf
(
"Error: %s
\n
"
,
c
->
errstr
);
return
1
;
}
size_t
len
;
const
char
*
val
=
RedisModule_StringPtrLen
(
argv
[
argc
-
1
],
&
len
);
RedisModuleCtx
*
module_ctx
=
RedisModule_GetDetachedThreadSafeContext
(
ctx
);
redisModuleAttach
(
c
,
module_ctx
);
redisAsyncSetConnectCallback
(
c
,
connectCallback
);
redisAsyncSetDisconnectCallback
(
c
,
disconnectCallback
);
redisAsyncSetTimeout
(
c
,
(
struct
timeval
){
.
tv_sec
=
1
,
.
tv_usec
=
0
});
/*
In this demo, we first `set key`, then `get key` to demonstrate the basic usage of the adapter.
Then in `getCallback`, we start a `debug sleep` command to create 1.5 second long request.
Because we have set a 1 second timeout to the connection, the command will always fail with a
timeout error, which is shown in the `debugCallback`.
*/
redisAsyncCommand
(
c
,
NULL
,
NULL
,
"SET key %b"
,
val
,
len
);
redisAsyncCommand
(
c
,
getCallback
,
(
char
*
)
"end-1"
,
"GET key"
);
return
0
;
}
deps/hiredis/examples/example-ssl.c
View file @
819d291b
...
...
@@ -12,7 +12,7 @@
int
main
(
int
argc
,
char
**
argv
)
{
unsigned
int
j
;
redisSSLContext
*
ssl
;
redisSSLContextError
ssl_error
;
redisSSLContextError
ssl_error
=
REDIS_SSL_CTX_NONE
;
redisContext
*
c
;
redisReply
*
reply
;
if
(
argc
<
4
)
{
...
...
@@ -27,9 +27,8 @@ int main(int argc, char **argv) {
redisInitOpenSSL
();
ssl
=
redisCreateSSLContext
(
ca
,
NULL
,
cert
,
key
,
NULL
,
&
ssl_error
);
if
(
!
ssl
)
{
printf
(
"SSL Context error: %s
\n
"
,
redisSSLContextGetError
(
ssl_error
));
if
(
!
ssl
||
ssl_error
!=
REDIS_SSL_CTX_NONE
)
{
printf
(
"SSL Context error: %s
\n
"
,
redisSSLContextGetError
(
ssl_error
));
exit
(
1
);
}
...
...
deps/hiredis/examples/example.c
View file @
819d291b
...
...
@@ -7,6 +7,54 @@
#include <winsock2.h>
/* For struct timeval */
#endif
static
void
example_argv_command
(
redisContext
*
c
,
size_t
n
)
{
char
**
argv
,
tmp
[
42
];
size_t
*
argvlen
;
redisReply
*
reply
;
/* We're allocating two additional elements for command and key */
argv
=
malloc
(
sizeof
(
*
argv
)
*
(
2
+
n
));
argvlen
=
malloc
(
sizeof
(
*
argvlen
)
*
(
2
+
n
));
/* First the command */
argv
[
0
]
=
(
char
*
)
"RPUSH"
;
argvlen
[
0
]
=
sizeof
(
"RPUSH"
)
-
1
;
/* Now our key */
argv
[
1
]
=
(
char
*
)
"argvlist"
;
argvlen
[
1
]
=
sizeof
(
"argvlist"
)
-
1
;
/* Now add the entries we wish to add to the list */
for
(
size_t
i
=
2
;
i
<
(
n
+
2
);
i
++
)
{
argvlen
[
i
]
=
snprintf
(
tmp
,
sizeof
(
tmp
),
"argv-element-%zu"
,
i
-
2
);
argv
[
i
]
=
strdup
(
tmp
);
}
/* Execute the command using redisCommandArgv. We're sending the arguments with
* two explicit arrays. One for each argument's string, and the other for its
* length. */
reply
=
redisCommandArgv
(
c
,
n
+
2
,
(
const
char
**
)
argv
,
(
const
size_t
*
)
argvlen
);
if
(
reply
==
NULL
||
c
->
err
)
{
fprintf
(
stderr
,
"Error: Couldn't execute redisCommandArgv
\n
"
);
exit
(
1
);
}
if
(
reply
->
type
==
REDIS_REPLY_INTEGER
)
{
printf
(
"%s reply: %lld
\n
"
,
argv
[
0
],
reply
->
integer
);
}
freeReplyObject
(
reply
);
/* Clean up */
for
(
size_t
i
=
2
;
i
<
(
n
+
2
);
i
++
)
{
free
(
argv
[
i
]);
}
free
(
argv
);
free
(
argvlen
);
}
int
main
(
int
argc
,
char
**
argv
)
{
unsigned
int
j
,
isunix
=
0
;
redisContext
*
c
;
...
...
@@ -87,6 +135,9 @@ int main(int argc, char **argv) {
}
freeReplyObject
(
reply
);
/* See function for an example of redisCommandArgv */
example_argv_command
(
c
,
10
);
/* Disconnects and frees the context */
redisFree
(
c
);
...
...
deps/hiredis/fuzzing/format_command_fuzzer.c
View file @
819d291b
...
...
@@ -48,10 +48,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
memcpy
(
new_str
,
data
,
size
);
new_str
[
size
]
=
'\0'
;
redisFormatCommand
(
&
cmd
,
new_str
);
if
(
cmd
!=
NULL
)
if
(
redisFormatCommand
(
&
cmd
,
new_str
)
!=
-
1
)
hi_free
(
cmd
);
free
(
new_str
);
return
0
;
}
deps/hiredis/hiredis-config.cmake.in
View file @
819d291b
...
...
@@ -2,11 +2,11 @@
set_and_check(hiredis_INCLUDEDIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
IF (NOT TARGET hiredis::hiredis)
IF (NOT TARGET hiredis::
@
hiredis
_export_name@
)
INCLUDE(${CMAKE_CURRENT_LIST_DIR}/hiredis-targets.cmake)
ENDIF()
SET(hiredis_LIBRARIES hiredis::hiredis)
SET(hiredis_LIBRARIES hiredis::
@
hiredis
_export_name@
)
SET(hiredis_INCLUDE_DIRS ${hiredis_INCLUDEDIR})
check_required_components(hiredis)
...
...
deps/hiredis/hiredis.c
View file @
819d291b
...
...
@@ -48,6 +48,7 @@ extern int redisContextUpdateConnectTimeout(redisContext *c, const struct timeva
extern
int
redisContextUpdateCommandTimeout
(
redisContext
*
c
,
const
struct
timeval
*
timeout
);
static
redisContextFuncs
redisContextDefaultFuncs
=
{
.
close
=
redisNetClose
,
.
free_privctx
=
NULL
,
.
async_read
=
redisAsyncRead
,
.
async_write
=
redisAsyncWrite
,
...
...
@@ -221,6 +222,9 @@ static void *createIntegerObject(const redisReadTask *task, long long value) {
static
void
*
createDoubleObject
(
const
redisReadTask
*
task
,
double
value
,
char
*
str
,
size_t
len
)
{
redisReply
*
r
,
*
parent
;
if
(
len
==
SIZE_MAX
)
// Prevents hi_malloc(0) if len equals to SIZE_MAX
return
NULL
;
r
=
createReplyObject
(
REDIS_REPLY_DOUBLE
);
if
(
r
==
NULL
)
return
NULL
;
...
...
@@ -399,6 +403,11 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
/* Copy va_list before consuming with va_arg */
va_copy
(
_cpy
,
ap
);
/* Make sure we have more characters otherwise strchr() accepts
* '\0' as an integer specifier. This is checked after above
* va_copy() to avoid UB in fmt_invalid's call to va_end(). */
if
(
*
_p
==
'\0'
)
goto
fmt_invalid
;
/* Integer conversion (without modifiers) */
if
(
strchr
(
intfmts
,
*
_p
)
!=
NULL
)
{
va_arg
(
ap
,
int
);
...
...
@@ -477,6 +486,8 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
touched
=
1
;
c
++
;
if
(
*
c
==
'\0'
)
break
;
}
c
++
;
}
...
...
@@ -719,7 +730,10 @@ static redisContext *redisContextInit(void) {
void
redisFree
(
redisContext
*
c
)
{
if
(
c
==
NULL
)
return
;
redisNetClose
(
c
);
if
(
c
->
funcs
&&
c
->
funcs
->
close
)
{
c
->
funcs
->
close
(
c
);
}
hi_sdsfree
(
c
->
obuf
);
redisReaderFree
(
c
->
reader
);
...
...
@@ -733,7 +747,7 @@ void redisFree(redisContext *c) {
if
(
c
->
privdata
&&
c
->
free_privdata
)
c
->
free_privdata
(
c
->
privdata
);
if
(
c
->
funcs
->
free_privctx
)
if
(
c
->
funcs
&&
c
->
funcs
->
free_privctx
)
c
->
funcs
->
free_privctx
(
c
->
privctx
);
memset
(
c
,
0xff
,
sizeof
(
*
c
));
...
...
@@ -756,7 +770,9 @@ int redisReconnect(redisContext *c) {
c
->
privctx
=
NULL
;
}
redisNetClose
(
c
);
if
(
c
->
funcs
&&
c
->
funcs
->
close
)
{
c
->
funcs
->
close
(
c
);
}
hi_sdsfree
(
c
->
obuf
);
redisReaderFree
(
c
->
reader
);
...
...
@@ -806,6 +822,12 @@ redisContext *redisConnectWithOptions(const redisOptions *options) {
if
(
options
->
options
&
REDIS_OPT_NOAUTOFREEREPLIES
)
{
c
->
flags
|=
REDIS_NO_AUTO_FREE_REPLIES
;
}
if
(
options
->
options
&
REDIS_OPT_PREFER_IPV4
)
{
c
->
flags
|=
REDIS_PREFER_IPV4
;
}
if
(
options
->
options
&
REDIS_OPT_PREFER_IPV6
)
{
c
->
flags
|=
REDIS_PREFER_IPV6
;
}
/* Set any user supplied RESP3 PUSH handler or use freeReplyObject
* as a default unless specifically flagged that we don't want one. */
...
...
@@ -838,7 +860,9 @@ redisContext *redisConnectWithOptions(const redisOptions *options) {
return
NULL
;
}
if
(
options
->
command_timeout
!=
NULL
&&
(
c
->
flags
&
REDIS_BLOCK
)
&&
c
->
fd
!=
REDIS_INVALID_FD
)
{
if
(
c
->
err
==
0
&&
c
->
fd
!=
REDIS_INVALID_FD
&&
options
->
command_timeout
!=
NULL
&&
(
c
->
flags
&
REDIS_BLOCK
))
{
redisContextSetTimeout
(
c
,
*
options
->
command_timeout
);
}
...
...
@@ -920,11 +944,18 @@ int redisSetTimeout(redisContext *c, const struct timeval tv) {
return
REDIS_ERR
;
}
int
redisEnableKeepAliveWithInterval
(
redisContext
*
c
,
int
interval
)
{
return
redisKeepAlive
(
c
,
interval
);
}
/* Enable connection KeepAlive. */
int
redisEnableKeepAlive
(
redisContext
*
c
)
{
if
(
redisKeepAlive
(
c
,
REDIS_KEEPALIVE_INTERVAL
)
!=
REDIS_OK
)
return
REDIS_ERR
;
return
REDIS_OK
;
return
redisKeepAlive
(
c
,
REDIS_KEEPALIVE_INTERVAL
);
}
/* Set the socket option TCP_USER_TIMEOUT. */
int
redisSetTcpUserTimeout
(
redisContext
*
c
,
unsigned
int
timeout
)
{
return
redisContextSetTcpUserTimeout
(
c
,
timeout
);
}
/* Set a user provided RESP3 PUSH handler and return any old one set. */
...
...
@@ -964,8 +995,8 @@ int redisBufferRead(redisContext *c) {
* successfully written to the socket. When the buffer is empty after the
* write operation, "done" is set to 1 (if given).
*
* Returns REDIS_ERR if an error occurred
try
in
g
t
o writ
e
a
nd
sets
* c->
errstr to hold the approp
ri
a
te
error string
.
* Returns REDIS_ERR if an
unrecoverable
error occurred in t
h
e
u
nd
erlying
* c->
funcs->w
rite
function
.
*/
int
redisBufferWrite
(
redisContext
*
c
,
int
*
done
)
{
...
...
deps/hiredis/hiredis.h
View file @
819d291b
...
...
@@ -46,9 +46,9 @@ typedef long long ssize_t;
#include "alloc.h"
/* for allocation wrappers */
#define HIREDIS_MAJOR 1
#define HIREDIS_MINOR
0
#define HIREDIS_PATCH
3
#define HIREDIS_SONAME 1.
0.3
-dev
#define HIREDIS_MINOR
1
#define HIREDIS_PATCH
1
#define HIREDIS_SONAME 1.
1.1
-dev
/* Connection type can be blocking or non-blocking and is set in the
* least significant bit of the flags field in redisContext. */
...
...
@@ -92,6 +92,11 @@ typedef long long ssize_t;
/* Flag that indicates the user does not want replies to be automatically freed */
#define REDIS_NO_AUTO_FREE_REPLIES 0x400
/* Flags to prefer IPv6 or IPv4 when doing DNS lookup. (If both are set,
* AF_UNSPEC is used.) */
#define REDIS_PREFER_IPV4 0x800
#define REDIS_PREFER_IPV6 0x1000
#define REDIS_KEEPALIVE_INTERVAL 15
/* seconds */
/* number of times we retry to connect in the case of EADDRNOTAVAIL and
...
...
@@ -149,20 +154,17 @@ struct redisSsl;
#define REDIS_OPT_NONBLOCK 0x01
#define REDIS_OPT_REUSEADDR 0x02
/**
* Don't automatically free the async object on a connection failure,
* or other implicit conditions. Only free on an explicit call to disconnect() or free()
*/
#define REDIS_OPT_NOAUTOFREE 0x04
/* Don't automatically intercept and free RESP3 PUSH replies. */
#define REDIS_OPT_NO_PUSH_AUTOFREE 0x08
/**
* Don't automatically free replies
*/
#define REDIS_OPT_NOAUTOFREEREPLIES 0x10
#define REDIS_OPT_NOAUTOFREE 0x04
/* Don't automatically free the async
* object on a connection failure, or
* other implicit conditions. Only free
* on an explicit call to disconnect()
* or free() */
#define REDIS_OPT_NO_PUSH_AUTOFREE 0x08
/* Don't automatically intercept and
* free RESP3 PUSH replies. */
#define REDIS_OPT_NOAUTOFREEREPLIES 0x10
/* Don't automatically free replies. */
#define REDIS_OPT_PREFER_IPV4 0x20
/* Prefer IPv4 in DNS lookups. */
#define REDIS_OPT_PREFER_IPV6 0x40
/* Prefer IPv6 in DNS lookups. */
#define REDIS_OPT_PREFER_IP_UNSPEC (REDIS_OPT_PREFER_IPV4 | REDIS_OPT_PREFER_IPV6)
/* In Unix systems a file descriptor is a regular signed int, with -1
* representing an invalid descriptor. In Windows it is a SOCKET
...
...
@@ -220,27 +222,37 @@ typedef struct {
/**
* Helper macros to initialize options to their specified fields.
*/
#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) \
(opts)->type = REDIS_CONN_TCP; \
(opts)->endpoint.tcp.ip = ip_; \
(opts)->endpoint.tcp.port = port_;
#define REDIS_OPTIONS_SET_UNIX(opts, path) \
(opts)->type = REDIS_CONN_UNIX; \
(opts)->endpoint.unix_socket = path;
#define REDIS_OPTIONS_SET_PRIVDATA(opts, data, dtor) \
(opts)->privdata = data; \
(opts)->free_privdata = dtor; \
#define REDIS_OPTIONS_SET_TCP(opts, ip_, port_) do { \
(opts)->type = REDIS_CONN_TCP; \
(opts)->endpoint.tcp.ip = ip_; \
(opts)->endpoint.tcp.port = port_; \
} while(0)
#define REDIS_OPTIONS_SET_UNIX(opts, path) do { \
(opts)->type = REDIS_CONN_UNIX; \
(opts)->endpoint.unix_socket = path; \
} while(0)
#define REDIS_OPTIONS_SET_PRIVDATA(opts, data, dtor) do { \
(opts)->privdata = data; \
(opts)->free_privdata = dtor; \
} while(0)
typedef
struct
redisContextFuncs
{
void
(
*
close
)(
struct
redisContext
*
);
void
(
*
free_privctx
)(
void
*
);
void
(
*
async_read
)(
struct
redisAsyncContext
*
);
void
(
*
async_write
)(
struct
redisAsyncContext
*
);
/* Read/Write data to the underlying communication stream, returning the
* number of bytes read/written. In the event of an unrecoverable error
* these functions shall return a value < 0. In the event of a
* recoverable error, they should return 0. */
ssize_t
(
*
read
)(
struct
redisContext
*
,
char
*
,
size_t
);
ssize_t
(
*
write
)(
struct
redisContext
*
);
}
redisContextFuncs
;
/* Context for a connection to Redis */
typedef
struct
redisContext
{
const
redisContextFuncs
*
funcs
;
/* Function table */
...
...
@@ -310,6 +322,8 @@ int redisReconnect(redisContext *c);
redisPushFn
*
redisSetPushCallback
(
redisContext
*
c
,
redisPushFn
*
fn
);
int
redisSetTimeout
(
redisContext
*
c
,
const
struct
timeval
tv
);
int
redisEnableKeepAlive
(
redisContext
*
c
);
int
redisEnableKeepAliveWithInterval
(
redisContext
*
c
,
int
interval
);
int
redisSetTcpUserTimeout
(
redisContext
*
c
,
unsigned
int
timeout
);
void
redisFree
(
redisContext
*
c
);
redisFD
redisFreeKeepFd
(
redisContext
*
c
);
int
redisBufferRead
(
redisContext
*
c
);
...
...
deps/hiredis/hiredis.pc.in
View file @
819d291b
...
...
@@ -9,4 +9,4 @@ Name: hiredis
Description: Minimalistic C client library for Redis.
Version: @PROJECT_VERSION@
Libs: -L${libdir} -lhiredis
Cflags: -I${pkgincludedir} -D_FILE_OFFSET_BITS=64
Cflags: -I${pkgincludedir}
-I${includedir}
-D_FILE_OFFSET_BITS=64
deps/hiredis/hiredis_ssl-config.cmake.in
View file @
819d291b
...
...
@@ -2,6 +2,9 @@
set_and_check(hiredis_ssl_INCLUDEDIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
include(CMakeFindDependencyMacro)
find_dependency(OpenSSL)
IF (NOT TARGET hiredis::hiredis_ssl)
INCLUDE(${CMAKE_CURRENT_LIST_DIR}/hiredis_ssl-targets.cmake)
ENDIF()
...
...
deps/hiredis/hiredis_ssl.h
View file @
819d291b
...
...
@@ -56,11 +56,33 @@ typedef enum {
REDIS_SSL_CTX_CERT_KEY_REQUIRED
,
/* Client cert and key must both be specified or skipped */
REDIS_SSL_CTX_CA_CERT_LOAD_FAILED
,
/* Failed to load CA Certificate or CA Path */
REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED
,
/* Failed to load client certificate */
REDIS_SSL_CTX_CLIENT_DEFAULT_CERT_FAILED
,
/* Failed to set client default certificate directory */
REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED
,
/* Failed to load private key */
REDIS_SSL_CTX_OS_CERTSTORE_OPEN_FAILED
,
/* Failed to open system certificate store */
REDIS_SSL_CTX_OS_CERT_ADD_FAILED
/* Failed to add CA certificates obtained from system to the SSL context */
}
redisSSLContextError
;
/* Constants that mirror OpenSSL's verify modes. By default,
* REDIS_SSL_VERIFY_PEER is used with redisCreateSSLContext().
* Some Redis clients disable peer verification if there are no
* certificates specified.
*/
#define REDIS_SSL_VERIFY_NONE 0x00
#define REDIS_SSL_VERIFY_PEER 0x01
#define REDIS_SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
#define REDIS_SSL_VERIFY_CLIENT_ONCE 0x04
#define REDIS_SSL_VERIFY_POST_HANDSHAKE 0x08
/* Options to create an OpenSSL context. */
typedef
struct
{
const
char
*
cacert_filename
;
const
char
*
capath
;
const
char
*
cert_filename
;
const
char
*
private_key_filename
;
const
char
*
server_name
;
int
verify_mode
;
}
redisSSLOptions
;
/**
* Return the error message corresponding with the specified error code.
*/
...
...
@@ -101,6 +123,18 @@ redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *
const
char
*
cert_filename
,
const
char
*
private_key_filename
,
const
char
*
server_name
,
redisSSLContextError
*
error
);
/**
* Helper function to initialize an OpenSSL context that can be used
* to initiate SSL connections. This is a more extensible version of redisCreateSSLContext().
*
* options contains a structure of SSL options to use.
*
* If error is non-null, it will be populated in case the context creation fails
* (returning a NULL).
*/
redisSSLContext
*
redisCreateSSLContextWithOptions
(
redisSSLOptions
*
options
,
redisSSLContextError
*
error
);
/**
* Free a previously created OpenSSL context.
*/
...
...
deps/hiredis/hiredis_ssl.pc.in
View file @
819d291b
prefix=@CMAKE_INSTALL_PREFIX@
install_libdir=@CMAKE_INSTALL_LIBDIR@
exec_prefix=${prefix}
libdir=${exec_prefix}/
lib
libdir=${exec_prefix}/
${install_libdir}
includedir=${prefix}/include
pkgincludedir=${includedir}/hiredis
...
...
deps/hiredis/net.c
View file @
819d291b
...
...
@@ -50,6 +50,8 @@
/* Defined in hiredis.c */
void
__redisSetError
(
redisContext
*
c
,
int
type
,
const
char
*
str
);
int
redisContextUpdateCommandTimeout
(
redisContext
*
c
,
const
struct
timeval
*
timeout
);
void
redisNetClose
(
redisContext
*
c
)
{
if
(
c
&&
c
->
fd
!=
REDIS_INVALID_FD
)
{
close
(
c
->
fd
);
...
...
@@ -68,7 +70,7 @@ ssize_t redisNetRead(redisContext *c, char *buf, size_t bufcap) {
__redisSetError
(
c
,
REDIS_ERR_TIMEOUT
,
"recv timeout"
);
return
-
1
;
}
else
{
__redisSetError
(
c
,
REDIS_ERR_IO
,
NULL
);
__redisSetError
(
c
,
REDIS_ERR_IO
,
strerror
(
errno
)
);
return
-
1
;
}
}
else
if
(
nread
==
0
)
{
...
...
@@ -80,15 +82,19 @@ ssize_t redisNetRead(redisContext *c, char *buf, size_t bufcap) {
}
ssize_t
redisNetWrite
(
redisContext
*
c
)
{
ssize_t
nwritten
=
send
(
c
->
fd
,
c
->
obuf
,
hi_sdslen
(
c
->
obuf
),
0
);
ssize_t
nwritten
;
nwritten
=
send
(
c
->
fd
,
c
->
obuf
,
hi_sdslen
(
c
->
obuf
),
0
);
if
(
nwritten
<
0
)
{
if
((
errno
==
EWOULDBLOCK
&&
!
(
c
->
flags
&
REDIS_BLOCK
))
||
(
errno
==
EINTR
))
{
/* Try again later */
/* Try again */
return
0
;
}
else
{
__redisSetError
(
c
,
REDIS_ERR_IO
,
NULL
);
__redisSetError
(
c
,
REDIS_ERR_IO
,
strerror
(
errno
)
);
return
-
1
;
}
}
return
nwritten
;
}
...
...
@@ -166,6 +172,7 @@ int redisKeepAlive(redisContext *c, int interval) {
int
val
=
1
;
redisFD
fd
=
c
->
fd
;
#ifndef _WIN32
if
(
setsockopt
(
fd
,
SOL_SOCKET
,
SO_KEEPALIVE
,
&
val
,
sizeof
(
val
))
==
-
1
){
__redisSetError
(
c
,
REDIS_ERR_OTHER
,
strerror
(
errno
));
return
REDIS_ERR
;
...
...
@@ -199,7 +206,15 @@ int redisKeepAlive(redisContext *c, int interval) {
}
#endif
#endif
#else
int
res
;
res
=
win32_redisKeepAlive
(
fd
,
interval
*
1000
);
if
(
res
!=
0
)
{
__redisSetError
(
c
,
REDIS_ERR_OTHER
,
strerror
(
res
));
return
REDIS_ERR
;
}
#endif
return
REDIS_OK
;
}
...
...
@@ -213,6 +228,22 @@ int redisSetTcpNoDelay(redisContext *c) {
return
REDIS_OK
;
}
int
redisContextSetTcpUserTimeout
(
redisContext
*
c
,
unsigned
int
timeout
)
{
int
res
;
#ifdef TCP_USER_TIMEOUT
res
=
setsockopt
(
c
->
fd
,
IPPROTO_TCP
,
TCP_USER_TIMEOUT
,
&
timeout
,
sizeof
(
timeout
));
#else
res
=
-
1
;
(
void
)
timeout
;
#endif
if
(
res
==
-
1
)
{
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
"setsockopt(TCP_USER_TIMEOUT)"
);
redisNetClose
(
c
);
return
REDIS_ERR
;
}
return
REDIS_OK
;
}
#define __MAX_MSEC (((LONG_MAX) - 999) / 1000)
static
int
redisContextTimeoutMsec
(
redisContext
*
c
,
long
*
result
)
...
...
@@ -223,6 +254,7 @@ static int redisContextTimeoutMsec(redisContext *c, long *result)
/* Only use timeout when not NULL. */
if
(
timeout
!=
NULL
)
{
if
(
timeout
->
tv_usec
>
1000000
||
timeout
->
tv_sec
>
__MAX_MSEC
)
{
__redisSetError
(
c
,
REDIS_ERR_IO
,
"Invalid timeout specified"
);
*
result
=
msec
;
return
REDIS_ERR
;
}
...
...
@@ -277,12 +309,28 @@ int redisCheckConnectDone(redisContext *c, int *completed) {
*
completed
=
1
;
return
REDIS_OK
;
}
switch
(
errno
)
{
int
error
=
errno
;
if
(
error
==
EINPROGRESS
)
{
/* must check error to see if connect failed. Get the socket error */
int
fail
,
so_error
;
socklen_t
optlen
=
sizeof
(
so_error
);
fail
=
getsockopt
(
c
->
fd
,
SOL_SOCKET
,
SO_ERROR
,
&
so_error
,
&
optlen
);
if
(
fail
==
0
)
{
if
(
so_error
==
0
)
{
/* Socket is connected! */
*
completed
=
1
;
return
REDIS_OK
;
}
/* connection error; */
errno
=
so_error
;
error
=
so_error
;
}
}
switch
(
error
)
{
case
EISCONN
:
*
completed
=
1
;
return
REDIS_OK
;
case
EALREADY
:
case
EINPROGRESS
:
case
EWOULDBLOCK
:
*
completed
=
0
;
return
REDIS_OK
;
...
...
@@ -317,6 +365,10 @@ int redisContextSetTimeout(redisContext *c, const struct timeval tv) {
const
void
*
to_ptr
=
&
tv
;
size_t
to_sz
=
sizeof
(
tv
);
if
(
redisContextUpdateCommandTimeout
(
c
,
&
tv
)
!=
REDIS_OK
)
{
__redisSetError
(
c
,
REDIS_ERR_OOM
,
"Out of memory"
);
return
REDIS_ERR
;
}
if
(
setsockopt
(
c
->
fd
,
SOL_SOCKET
,
SO_RCVTIMEO
,
to_ptr
,
to_sz
)
==
-
1
)
{
__redisSetErrorFromErrno
(
c
,
REDIS_ERR_IO
,
"setsockopt(SO_RCVTIMEO)"
);
return
REDIS_ERR
;
...
...
@@ -400,7 +452,6 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
}
if
(
redisContextTimeoutMsec
(
c
,
&
timeout_msec
)
!=
REDIS_OK
)
{
__redisSetError
(
c
,
REDIS_ERR_IO
,
"Invalid timeout specified"
);
goto
error
;
}
...
...
@@ -417,17 +468,25 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
hints
.
ai_family
=
AF_INET
;
hints
.
ai_socktype
=
SOCK_STREAM
;
/* Try with IPv6 if no IPv4 address was found. We do it in this order since
* in a Redis client you can't afford to test if you have IPv6 connectivity
* as this would add latency to every connect. Otherwise a more sensible
* route could be: Use IPv6 if both addresses are available and there is IPv6
* connectivity. */
if
((
rv
=
getaddrinfo
(
c
->
tcp
.
host
,
_port
,
&
hints
,
&
servinfo
))
!=
0
)
{
hints
.
ai_family
=
AF_INET6
;
if
((
rv
=
getaddrinfo
(
addr
,
_port
,
&
hints
,
&
servinfo
))
!=
0
)
{
__redisSetError
(
c
,
REDIS_ERR_OTHER
,
gai_strerror
(
rv
));
return
REDIS_ERR
;
}
/* DNS lookup. To use dual stack, set both flags to prefer both IPv4 and
* IPv6. By default, for historical reasons, we try IPv4 first and then we
* try IPv6 only if no IPv4 address was found. */
if
(
c
->
flags
&
REDIS_PREFER_IPV6
&&
c
->
flags
&
REDIS_PREFER_IPV4
)
hints
.
ai_family
=
AF_UNSPEC
;
else
if
(
c
->
flags
&
REDIS_PREFER_IPV6
)
hints
.
ai_family
=
AF_INET6
;
else
hints
.
ai_family
=
AF_INET
;
rv
=
getaddrinfo
(
c
->
tcp
.
host
,
_port
,
&
hints
,
&
servinfo
);
if
(
rv
!=
0
&&
hints
.
ai_family
!=
AF_UNSPEC
)
{
/* Try again with the other IP version. */
hints
.
ai_family
=
(
hints
.
ai_family
==
AF_INET
)
?
AF_INET6
:
AF_INET
;
rv
=
getaddrinfo
(
c
->
tcp
.
host
,
_port
,
&
hints
,
&
servinfo
);
}
if
(
rv
!=
0
)
{
__redisSetError
(
c
,
REDIS_ERR_OTHER
,
gai_strerror
(
rv
));
return
REDIS_ERR
;
}
for
(
p
=
servinfo
;
p
!=
NULL
;
p
=
p
->
ai_next
)
{
addrretry:
...
...
deps/hiredis/net.h
View file @
819d291b
...
...
@@ -52,5 +52,6 @@ int redisKeepAlive(redisContext *c, int interval);
int
redisCheckConnectDone
(
redisContext
*
c
,
int
*
completed
);
int
redisSetTcpNoDelay
(
redisContext
*
c
);
int
redisContextSetTcpUserTimeout
(
redisContext
*
c
,
unsigned
int
timeout
);
#endif
deps/hiredis/read.c
View file @
819d291b
...
...
@@ -303,11 +303,14 @@ static int processLineItem(redisReader *r) {
d
=
INFINITY
;
/* Positive infinite. */
}
else
if
(
len
==
4
&&
strcasecmp
(
buf
,
"-inf"
)
==
0
)
{
d
=
-
INFINITY
;
/* Negative infinite. */
}
else
if
((
len
==
3
&&
strcasecmp
(
buf
,
"nan"
)
==
0
)
||
(
len
==
4
&&
strcasecmp
(
buf
,
"-nan"
)
==
0
))
{
d
=
NAN
;
/* nan. */
}
else
{
d
=
strtod
((
char
*
)
buf
,
&
eptr
);
/* RESP3 only allows "inf", "-inf", and finite values, while
* strtod() allows other variations on infinity,
NaN,
* etc. We explicity handle our two allowed infinite cases
* strtod() allows other variations on infinity,
* etc. We explicity handle our two allowed infinite cases
and NaN
* above, so strtod() should only result in finite values. */
if
(
buf
[
0
]
==
'\0'
||
eptr
!=
&
buf
[
len
]
||
!
isfinite
(
d
))
{
__redisReaderSetError
(
r
,
REDIS_ERR_PROTOCOL
,
...
...
@@ -374,7 +377,7 @@ static int processLineItem(redisReader *r) {
if
(
r
->
fn
&&
r
->
fn
->
createString
)
obj
=
r
->
fn
->
createString
(
cur
,
p
,
len
);
else
obj
=
(
void
*
)(
size
_t
)(
cur
->
type
);
obj
=
(
void
*
)(
uintptr
_t
)(
cur
->
type
);
}
if
(
obj
==
NULL
)
{
...
...
@@ -439,7 +442,7 @@ static int processBulkItem(redisReader *r) {
if
(
r
->
fn
&&
r
->
fn
->
createString
)
obj
=
r
->
fn
->
createString
(
cur
,
s
+
2
,
len
);
else
obj
=
(
void
*
)(
long
)
cur
->
type
;
obj
=
(
void
*
)(
uintptr_t
)
cur
->
type
;
success
=
1
;
}
}
...
...
@@ -536,7 +539,7 @@ static int processAggregateItem(redisReader *r) {
if
(
r
->
fn
&&
r
->
fn
->
createArray
)
obj
=
r
->
fn
->
createArray
(
cur
,
elements
);
else
obj
=
(
void
*
)(
long
)
cur
->
type
;
obj
=
(
void
*
)(
uintptr_t
)
cur
->
type
;
if
(
obj
==
NULL
)
{
__redisReaderSetErrorOOM
(
r
);
...
...
deps/hiredis/sds.c
View file @
819d291b
...
...
@@ -90,6 +90,7 @@ hisds hi_sdsnewlen(const void *init, size_t initlen) {
int
hdrlen
=
hi_sdsHdrSize
(
type
);
unsigned
char
*
fp
;
/* flags pointer. */
if
(
hdrlen
+
initlen
+
1
<=
initlen
)
return
NULL
;
/* Catch size_t overflow */
sh
=
hi_s_malloc
(
hdrlen
+
initlen
+
1
);
if
(
sh
==
NULL
)
return
NULL
;
if
(
!
init
)
...
...
@@ -174,7 +175,7 @@ void hi_sdsfree(hisds s) {
* the output will be "6" as the string was modified but the logical length
* remains 6 bytes. */
void
hi_sdsupdatelen
(
hisds
s
)
{
in
t
reallen
=
strlen
(
s
);
size_
t
reallen
=
strlen
(
s
);
hi_sdssetlen
(
s
,
reallen
);
}
...
...
@@ -196,7 +197,7 @@ void hi_sdsclear(hisds s) {
hisds
hi_sdsMakeRoomFor
(
hisds
s
,
size_t
addlen
)
{
void
*
sh
,
*
newsh
;
size_t
avail
=
hi_sdsavail
(
s
);
size_t
len
,
newlen
;
size_t
len
,
newlen
,
reqlen
;
char
type
,
oldtype
=
s
[
-
1
]
&
HI_SDS_TYPE_MASK
;
int
hdrlen
;
...
...
@@ -205,7 +206,8 @@ hisds hi_sdsMakeRoomFor(hisds s, size_t addlen) {
len
=
hi_sdslen
(
s
);
sh
=
(
char
*
)
s
-
hi_sdsHdrSize
(
oldtype
);
newlen
=
(
len
+
addlen
);
reqlen
=
newlen
=
(
len
+
addlen
);
if
(
newlen
<=
len
)
return
NULL
;
/* Catch size_t overflow */
if
(
newlen
<
HI_SDS_MAX_PREALLOC
)
newlen
*=
2
;
else
...
...
@@ -219,6 +221,7 @@ hisds hi_sdsMakeRoomFor(hisds s, size_t addlen) {
if
(
type
==
HI_SDS_TYPE_5
)
type
=
HI_SDS_TYPE_8
;
hdrlen
=
hi_sdsHdrSize
(
type
);
if
(
hdrlen
+
newlen
+
1
<=
reqlen
)
return
NULL
;
/* Catch size_t overflow */
if
(
oldtype
==
type
)
{
newsh
=
hi_s_realloc
(
sh
,
hdrlen
+
newlen
+
1
);
if
(
newsh
==
NULL
)
return
NULL
;
...
...
@@ -580,7 +583,7 @@ hisds hi_sdscatprintf(hisds s, const char *fmt, ...) {
*/
hisds
hi_sdscatfmt
(
hisds
s
,
char
const
*
fmt
,
...)
{
const
char
*
f
=
fmt
;
int
i
;
long
i
;
va_list
ap
;
va_start
(
ap
,
fmt
);
...
...
@@ -753,16 +756,16 @@ int hi_sdsrange(hisds s, ssize_t start, ssize_t end) {
return
0
;
}
/* Apply tolower() to every character of the
hi
sds string 's'. */
/* Apply tolower() to every character of the sds string 's'. */
void
hi_sdstolower
(
hisds
s
)
{
in
t
len
=
hi_sdslen
(
s
),
j
;
size_
t
len
=
hi_sdslen
(
s
),
j
;
for
(
j
=
0
;
j
<
len
;
j
++
)
s
[
j
]
=
tolower
(
s
[
j
]);
}
/* Apply toupper() to every character of the
hi
sds string 's'. */
/* Apply toupper() to every character of the sds string 's'. */
void
hi_sdstoupper
(
hisds
s
)
{
in
t
len
=
hi_sdslen
(
s
),
j
;
size_
t
len
=
hi_sdslen
(
s
),
j
;
for
(
j
=
0
;
j
<
len
;
j
++
)
s
[
j
]
=
toupper
(
s
[
j
]);
}
...
...
deps/hiredis/sds.h
View file @
819d291b
...
...
@@ -35,9 +35,11 @@
#define HI_SDS_MAX_PREALLOC (1024*1024)
#ifdef _MSC_VER
#define __attribute__(x)
typedef
long
long
ssize_t
;
#define SSIZE_MAX (LLONG_MAX >> 1)
#ifndef __clang__
#define __attribute__(x)
#endif
#endif
#include <sys/types.h>
...
...
Prev
1
2
3
4
5
6
…
8
Next
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