diff options
author | oranagra <oran@redislabs.com> | 2016-05-10 11:19:45 +0300 |
---|---|---|
committer | oranagra <oran@redislabs.com> | 2016-05-10 11:19:45 +0300 |
commit | 77a91442452548e901c2830c7e6b77c4e542d4bb (patch) | |
tree | 7c16c75056c470e9cbd71bd88e8efa06745a3432 /src/bitops.c | |
parent | 3b644e82b0cc96113e29672d1551248c9e9db893 (diff) | |
download | redis-77a91442452548e901c2830c7e6b77c4e542d4bb.tar.gz |
fix crash in BITFIELD GET when key is integer encoded
Diffstat (limited to 'src/bitops.c')
-rw-r--r-- | src/bitops.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/bitops.c b/src/bitops.c index ed7e384a0..0dbbeb6e4 100644 --- a/src/bitops.c +++ b/src/bitops.c @@ -1035,16 +1035,28 @@ void bitfieldCommand(client *c) { changes++; } else { /* GET */ - o = lookupKeyRead(c->db,c->argv[1]); - size_t olen = (o == NULL) ? 0 : sdslen(o->ptr); unsigned char buf[9]; + size_t olen = 0; + unsigned char *src = NULL; + char llbuf[32]; + + o = lookupKeyRead(c->db,c->argv[1]); + + /* Set the 'p' pointer to the string, that can be just a stack allocated + * array if our string was integer encoded. */ + if (o && o->encoding == OBJ_ENCODING_INT) { + src = (unsigned char*) llbuf; + olen = ll2string(llbuf,sizeof(llbuf),(long)o->ptr); + } else if (o) { + src = (unsigned char*) o->ptr; + olen = sdslen(o->ptr); + } /* For GET we use a trick: before executing the operation * copy up to 9 bytes to a local buffer, so that we can easily * execute up to 64 bit operations that are at actual string * object boundaries. */ memset(buf,0,9); - unsigned char *src = o ? o->ptr : NULL; int i; size_t byte = thisop->offset >> 3; for (i = 0; i < 9; i++) { |