Commit 38c799c9 authored by Sergey Vojtovich's avatar Sergey Vojtovich

MDEV-15763 - VARCHAR(1) COMPRESSED crashes the server

Storing 1 byte long string in VARCHAR() COMPRESSED column may trigger
integer overflow when calculating available space for zlib output.
parent 3dec6c48
......@@ -1386,3 +1386,11 @@ SELECT LENGTH(a) FROM t1;
LENGTH(a)
0
DROP TABLE t1;
#
# MDEV-15763 - VARCHAR(1) COMPRESSED crashes the server
#
CREATE TABLE t1(a VARCHAR(1) COMPRESSED);
SET column_compression_threshold=0;
INSERT INTO t1 VALUES('a');
SET column_compression_threshold=DEFAULT;
DROP TABLE t1;
......@@ -102,3 +102,13 @@ INSERT INTO t1 VALUES('a');
INSERT INTO t1 VALUES(' ');
SELECT LENGTH(a) FROM t1;
DROP TABLE t1;
--echo #
--echo # MDEV-15763 - VARCHAR(1) COMPRESSED crashes the server
--echo #
CREATE TABLE t1(a VARCHAR(1) COMPRESSED);
SET column_compression_threshold=0;
INSERT INTO t1 VALUES('a');
SET column_compression_threshold=DEFAULT;
DROP TABLE t1;
......@@ -21,11 +21,30 @@
#include <zlib.h>
/**
Compresses string using zlib
@param[out] to destination buffer for compressed data
@param[in] from data to compress
@param[in] length from length
Requirement is such that string stored at `to' must not exceed `from' length.
Otherwise 0 is returned and caller stores string uncompressed.
`to' must be large enough to hold `length' bytes.
length == 1 is an edge case that may break stream.avail_out calculation: at
least 2 bytes required to store metadata.
*/
static uint compress_zlib(THD *thd, char *to, const char *from, uint length)
{
uint level= thd->variables.column_compression_zlib_level;
if (level > 0)
/* Caller takes care of empty strings. */
DBUG_ASSERT(length);
if (level > 0 && length > 1)
{
z_stream stream;
int wbits= thd->variables.column_compression_zlib_wrap ? MAX_WBITS :
......@@ -40,6 +59,7 @@ static uint compress_zlib(THD *thd, char *to, const char *from, uint length)
stream.avail_in= length;
stream.next_in= (Bytef*) from;
DBUG_ASSERT(length >= original_pack_length + 1);
stream.avail_out= length - original_pack_length - 1;
stream.next_out= (Bytef*) to + original_pack_length + 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment