mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 11:45:32 +00:00
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.
This commit is contained in:
@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user