8000 Fix LZF decompression logic. (#2065) · phpredis/phpredis@d938a42 · GitHub
[go: up one dir, main page]

Skip to content

Commit d938a42

Browse files
michael-grunderyatsukhnenko
authored andcommitted
Fix LZF decompression logic. (#2065)
* Fix LZF decompression logic. Rework how we decompress LZF data. Previously it was possible to encounter a double-free, if the error was not E2BIG. * .
1 parent e849b53 commit d938a42

File tree

2 files changed

+16
-13
lines changed

2 files changed

+16
-13
lines changed

library.c

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2941,27 +2941,22 @@ redis_uncompress(RedisSock *redis_sock, char **dst, size_t *dstlen, const char *
29412941
case REDIS_COMPRESSION_LZF:
29422942
#ifdef HAVE_REDIS_LZF
29432943
{
2944-
char *data;
2945-
int i;
2944+
char *data = NULL;
29462945
uint32_t res;
2946+
int i;
29472947

29482948
if (len == 0)
29492949
break;
29502950

2951-
/* start from two-times bigger buffer and
2952-
* increase it exponentially if needed */
2951+
/* Grow our buffer until we succeed or get a non E2BIG error */
29532952
errno = E2BIG;
29542953
for (i = 2; errno == E2BIG; i *= 2) {
2955-
data = emalloc(i * len);
2956-
if ((res = lzf_decompress(src, len, data, i * len)) == 0) {
2957-
/* errno != E2BIG will brake for loop */
2958-
efree(data);
2959-
continue;
2954+
data = erealloc(data, len * i);
2955+
if ((res = lzf_decompress(src, len, data, len * i)) > 0) {
2956+
*dst = data;
2957+
*dstlen = res;
2958+
return 1;
29602959
}
2961-
2962-
*dst = data;
2963-
*dstlen = res;
2964-
return 1;
29652960
}
29662961

29672962
efree(data);

tests/RedisTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4584,6 +4584,14 @@ public function testCompressionLZF()
45844584
if (!defined('Redis::COMPRESSION_LZF')) {
45854585
$this->markTestSkipped();
45864586
}
4587+
4588+
/* Don't crash on improperly compressed LZF data */
4589+
$payload = 'not-actually-lzf-compressed';
4590+
$this->redis->set('badlzf', $payload);
4591+
$this->redis->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_LZF);
4592+
$this->assertEquals($payload, $this->redis->get('badlzf'));
4593+
$this->redis->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_NONE);
4594+
45874595
$this->checkCompression(Redis::COMPRESSION_LZF, 0);
45884596
}
45894597

0 commit comments

Comments
 (0)
0