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
5c9f49e2
Unverified
Commit
5c9f49e2
authored
May 19, 2020
by
Michael Grunder
Committed by
GitHub
May 19, 2020
Browse files
Resp3 verbatim string support (#805)
Pull RESP3 verbatim string handling from Redis Fixes #802
parent
243099cc
Changes
5
Hide whitespace changes
Inline
Side-by-side
hiredis.c
View file @
5c9f49e2
...
...
@@ -107,6 +107,7 @@ void freeReplyObject(void *reply) {
case
REDIS_REPLY_STATUS
:
case
REDIS_REPLY_STRING
:
case
REDIS_REPLY_DOUBLE
:
case
REDIS_REPLY_VERB
:
free
(
r
->
str
);
break
;
}
...
...
@@ -121,21 +122,34 @@ static void *createStringObject(const redisReadTask *task, char *str, size_t len
if
(
r
==
NULL
)
return
NULL
;
buf
=
malloc
(
len
+
1
);
if
(
buf
==
NULL
)
{
freeReplyObject
(
r
);
return
NULL
;
}
assert
(
task
->
type
==
REDIS_REPLY_ERROR
||
task
->
type
==
REDIS_REPLY_STATUS
||
task
->
type
==
REDIS_REPLY_STRING
);
task
->
type
==
REDIS_REPLY_STRING
||
task
->
type
==
REDIS_REPLY_VERB
);
/* Copy string value */
memcpy
(
buf
,
str
,
len
);
buf
[
len
]
=
'\0'
;
if
(
task
->
type
==
REDIS_REPLY_VERB
)
{
buf
=
malloc
(
len
-
4
+
1
);
/* Skip 4 bytes of verbatim type header. */
if
(
buf
==
NULL
)
{
freeReplyObject
(
r
);
return
NULL
;
}
memcpy
(
r
->
vtype
,
str
,
3
);
r
->
vtype
[
3
]
=
'\0'
;
memcpy
(
buf
,
str
+
4
,
len
-
4
);
buf
[
len
-
4
]
=
'\0'
;
r
->
len
=
len
-
4
;
}
else
{
buf
=
malloc
(
len
+
1
);
if
(
buf
==
NULL
)
{
freeReplyObject
(
r
);
return
NULL
;
}
memcpy
(
buf
,
str
,
len
);
buf
[
len
]
=
'\0'
;
r
->
len
=
len
;
}
r
->
str
=
buf
;
r
->
len
=
len
;
if
(
task
->
parent
)
{
parent
=
task
->
parent
->
obj
;
...
...
hiredis.h
View file @
5c9f49e2
...
...
@@ -102,7 +102,9 @@ typedef struct redisReply {
double
dval
;
/* The double when type is REDIS_REPLY_DOUBLE */
size_t
len
;
/* Length of string */
char
*
str
;
/* Used for REDIS_REPLY_ERROR, REDIS_REPLY_STRING
and REDIS_REPLY_DOUBLE (in additional to dval). */
REDIS_REPLY_VERB, and REDIS_REPLY_DOUBLE (in additional to dval). */
char
vtype
[
4
];
/* Used for REDIS_REPLY_VERB, contains the null
terminated 3 character content type, such as "txt". */
size_t
elements
;
/* number of elements, for REDIS_REPLY_ARRAY */
struct
redisReply
**
element
;
/* elements vector for REDIS_REPLY_ARRAY */
}
redisReply
;
...
...
read.c
View file @
5c9f49e2
...
...
@@ -383,10 +383,18 @@ static int processBulkItem(redisReader *r) {
/* Only continue when the buffer contains the entire bulk item. */
bytelen
+=
len
+
2
;
/* include \r\n */
if
(
r
->
pos
+
bytelen
<=
r
->
len
)
{
if
((
cur
->
type
==
REDIS_REPLY_VERB
&&
len
<
4
)
||
(
cur
->
type
==
REDIS_REPLY_VERB
&&
s
[
5
]
!=
':'
))
{
__redisReaderSetError
(
r
,
REDIS_ERR_PROTOCOL
,
"Verbatim string 4 bytes of content type are "
"missing or incorrectly encoded."
);
return
REDIS_ERR
;
}
if
(
r
->
fn
&&
r
->
fn
->
createString
)
obj
=
r
->
fn
->
createString
(
cur
,
s
+
2
,
len
);
else
obj
=
(
void
*
)
REDIS_REPLY_STRING
;
obj
=
(
void
*
)
(
long
)
cur
->
type
;
success
=
1
;
}
}
...
...
@@ -551,6 +559,9 @@ static int processItem(redisReader *r) {
case
'#'
:
cur
->
type
=
REDIS_REPLY_BOOL
;
break
;
case
'='
:
cur
->
type
=
REDIS_REPLY_VERB
;
break
;
default:
__redisReaderSetErrorProtocolByte
(
r
,
*
p
);
return
REDIS_ERR
;
...
...
@@ -571,6 +582,7 @@ static int processItem(redisReader *r) {
case
REDIS_REPLY_BOOL
:
return
processLineItem
(
r
);
case
REDIS_REPLY_STRING
:
case
REDIS_REPLY_VERB
:
return
processBulkItem
(
r
);
case
REDIS_REPLY_ARRAY
:
case
REDIS_REPLY_MAP
:
...
...
read.h
View file @
5c9f49e2
...
...
@@ -56,12 +56,12 @@
#define REDIS_REPLY_ERROR 6
#define REDIS_REPLY_DOUBLE 7
#define REDIS_REPLY_BOOL 8
#define REDIS_REPLY_VERB 9
#define REDIS_REPLY_MAP 9
#define REDIS_REPLY_SET 10
#define REDIS_REPLY_ATTR 11
#define REDIS_REPLY_PUSH 12
#define REDIS_REPLY_BIGNUM 13
#define REDIS_REPLY_VERB 14
#define REDIS_READER_MAX_BUF (1024*16)
/* Default max unused reader buffer. */
...
...
test.c
View file @
5c9f49e2
...
...
@@ -477,6 +477,17 @@ static void test_reply_reader(void) {
((
redisReply
*
)
reply
)
->
elements
==
0
);
freeReplyObject
(
reply
);
redisReaderFree
(
reader
);
/* RESP3 verbatim strings (GitHub issue #802) */
test
(
"Can parse RESP3 verbatim strings: "
);
reader
=
redisReaderCreate
();
redisReaderFeed
(
reader
,(
char
*
)
"=10
\r\n
txt:LOLWUT
\r\n
"
,
17
);
ret
=
redisReaderGetReply
(
reader
,
&
reply
);
test_cond
(
ret
==
REDIS_OK
&&
((
redisReply
*
)
reply
)
->
type
==
REDIS_REPLY_VERB
&&
!
memcmp
(((
redisReply
*
)
reply
)
->
str
,
"LOLWUT"
,
6
));
freeReplyObject
(
reply
);
redisReaderFree
(
reader
);
}
static
void
test_free_null
(
void
)
{
...
...
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