Fix BITPOS unaligned memory access.

This commit is contained in:
Salvatore Sanfilippo 2017-02-23 22:38:44 +08:00
parent 06263485d4
commit d7826823c0

View File

@ -104,6 +104,7 @@ long redisBitpos(void *s, unsigned long count, int bit) {
unsigned long skipval, word = 0, one;
long pos = 0; /* Position of bit, to return to the caller. */
unsigned long j;
int found;
/* Process whole words first, seeking for first word that is not
* all ones or all zeros respectively if we are lookig for zeros
@ -117,21 +118,27 @@ long redisBitpos(void *s, unsigned long count, int bit) {
/* Skip initial bits not aligned to sizeof(unsigned long) byte by byte. */
skipval = bit ? 0 : UCHAR_MAX;
c = (unsigned char*) s;
found = 0;
while((unsigned long)c & (sizeof(*l)-1) && count) {
if (*c != skipval) break;
if (*c != skipval) {
found = 1;
break;
}
c++;
count--;
pos += 8;
}
/* Skip bits with full word step. */
skipval = bit ? 0 : ULONG_MAX;
l = (unsigned long*) c;
while (count >= sizeof(*l)) {
if (*l != skipval) break;
l++;
count -= sizeof(*l);
pos += sizeof(*l)*8;
if (!found) {
skipval = bit ? 0 : ULONG_MAX;
while (count >= sizeof(*l)) {
if (*l != skipval) break;
l++;
count -= sizeof(*l);
pos += sizeof(*l)*8;
}
}
/* Load bytes into "word" considering the first byte as the most significant