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
33a9836f
Commit
33a9836f
authored
Jun 16, 2016
by
Salvatore Sanfilippo
Committed by
GitHub
Jun 16, 2016
Browse files
Merge pull request #3264 from oranagra/bitfield_fix2
fix crash in BITFIELD GET on non existing key or wrong type see #3259
parents
5d83f6cf
5d96b7ed
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/bitops.c
View file @
33a9836f
...
...
@@ -906,6 +906,8 @@ void bitfieldCommand(client *c) {
int
j
,
numops
=
0
,
changes
=
0
;
struct
bitfieldOp
*
ops
=
NULL
;
/* Array of ops to execute at end. */
int
owtype
=
BFOVERFLOW_WRAP
;
/* Overflow type. */
int
readonly
=
1
;
long
highestWriteOffset
=
0
;
for
(
j
=
2
;
j
<
c
->
argc
;
j
++
)
{
int
remargs
=
c
->
argc
-
j
-
1
;
/* Remaining args other than current. */
...
...
@@ -953,8 +955,10 @@ void bitfieldCommand(client *c) {
return
;
}
/* INCRBY and SET require another argument. */
if
(
opcode
!=
BITFIELDOP_GET
)
{
readonly
=
0
;
highestWriteOffset
=
bitoffset
+
bits
-
1
;
/* INCRBY and SET require another argument. */
if
(
getLongLongFromObjectOrReply
(
c
,
c
->
argv
[
j
+
3
],
&
i64
,
NULL
)
!=
C_OK
){
zfree
(
ops
);
return
;
...
...
@@ -974,6 +978,18 @@ void bitfieldCommand(client *c) {
j
+=
3
-
(
opcode
==
BITFIELDOP_GET
);
}
if
(
readonly
)
{
/* Lookup for read is ok if key doesn't exit, but errors
* if it's not a string*/
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
if
(
o
!=
NULL
&&
checkType
(
c
,
o
,
OBJ_STRING
))
return
;
}
else
{
/* Lookup by making room up to the farest bit reached by
* this operation. */
if
((
o
=
lookupStringForBitCommand
(
c
,
highestWriteOffset
))
==
NULL
)
return
;
}
addReplyMultiBulkLen
(
c
,
numops
);
/* Actually process the operations. */
...
...
@@ -988,11 +1004,6 @@ void bitfieldCommand(client *c) {
* for simplicity. SET return value is the previous value so
* we need fetch & store as well. */
/* Lookup by making room up to the farest bit reached by
* this operation. */
if
((
o
=
lookupStringForBitCommand
(
c
,
thisop
->
offset
+
(
thisop
->
bits
-
1
)))
==
NULL
)
return
;
/* We need two different but very similar code paths for signed
* and unsigned operations, since the set of functions to get/set
* the integers and the used variables types are different. */
...
...
@@ -1060,12 +1071,12 @@ void bitfieldCommand(client *c) {
}
else
{
/* GET */
unsigned
char
buf
[
9
];
long
strlen
;
long
strlen
=
0
;
unsigned
char
*
src
=
NULL
;
char
llbuf
[
LONG_STR_SIZE
];
o
=
lookupKeyRead
(
c
->
db
,
c
->
argv
[
1
]);
src
=
getObjectReadOnlyString
(
o
,
&
strlen
,
llbuf
);
if
(
o
!
=
NULL
)
src
=
getObjectReadOnlyString
(
o
,
&
strlen
,
llbuf
);
/* For GET we use a trick: before executing the operation
* copy up to 9 bytes to a local buffer, so that we can easily
...
...
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