mirror of https://github.com/postgres/postgres
The goal of this module is to provide an entry point for the coverage of
the low-level compression and decompression PGLZ routines. The new test
is moved to a new parallel group, with all the existing
compression-related tests added to it.
This includes tests for the cases detected by fuzzing that emulate
corrupted compressed data, as fixed by 2b5ba2a0a141:
- Set control bit with read of a match tag, where no data follows.
- Set control bit with read of a match tag, where 1 byte follows.
- Set control bit with match tag where length nibble is 3 bytes
(extended case).
While on it, some tests are added for compress/decompress roundtrips,
and for check_complete=false/true. Like 2b5ba2a0a1, backpatch to all
the stable branches.
Discussion: https://postgr.es/m/adw647wuGjh1oU6p@paquier.xyz
Backpatch-through: 14
master
parent
66ad764c8d
commit
67d318e704
@ -0,0 +1,65 @@ |
||||
-- |
||||
-- Tests for PGLZ compression |
||||
-- |
||||
-- directory paths and dlsuffix are passed to us in environment variables |
||||
\getenv libdir PG_LIBDIR |
||||
\getenv dlsuffix PG_DLSUFFIX |
||||
\set regresslib :libdir '/regress' :dlsuffix |
||||
CREATE FUNCTION test_pglz_compress(bytea) |
||||
RETURNS bytea |
||||
AS :'regresslib' LANGUAGE C STRICT; |
||||
CREATE FUNCTION test_pglz_decompress(bytea, int4, bool) |
||||
RETURNS bytea |
||||
AS :'regresslib' LANGUAGE C STRICT; |
||||
-- Round-trip with pglz: compress then decompress. |
||||
SELECT test_pglz_decompress(test_pglz_compress( |
||||
decode(repeat('abcd', 100), 'escape')), 400, false) = |
||||
decode(repeat('abcd', 100), 'escape') AS roundtrip_ok; |
||||
roundtrip_ok |
||||
-------------- |
||||
t |
||||
(1 row) |
||||
|
||||
SELECT test_pglz_decompress(test_pglz_compress( |
||||
decode(repeat('abcd', 100), 'escape')), 400, true) = |
||||
decode(repeat('abcd', 100), 'escape') AS roundtrip_ok; |
||||
roundtrip_ok |
||||
-------------- |
||||
t |
||||
(1 row) |
||||
|
||||
-- Decompression with rawsize too large, fails to fill the destination |
||||
-- buffer. |
||||
SELECT test_pglz_decompress(test_pglz_compress( |
||||
decode(repeat('abcd', 100), 'escape')), 500, true); |
||||
ERROR: pglz_decompress failed |
||||
-- Decompression with rawsize too small, fails with source not fully |
||||
-- consumed. |
||||
SELECT test_pglz_decompress(test_pglz_compress( |
||||
decode(repeat('abcd', 100), 'escape')), 100, true); |
||||
ERROR: pglz_decompress failed |
||||
-- Corrupted compressed data. Set control bit with read of a match tag, |
||||
-- no data follows. |
||||
SELECT length(test_pglz_decompress('\x01'::bytea, 1024, false)) AS ctrl_only_len; |
||||
ctrl_only_len |
||||
--------------- |
||||
0 |
||||
(1 row) |
||||
|
||||
SELECT test_pglz_decompress('\x01'::bytea, 1024, true); |
||||
ERROR: pglz_decompress failed |
||||
-- Corrupted compressed data. Set control bit with read of a match tag, |
||||
-- 1 byte follows. |
||||
SELECT test_pglz_decompress('\x01ff'::bytea, 1024, false); |
||||
ERROR: pglz_decompress failed |
||||
SELECT test_pglz_decompress('\x01ff'::bytea, 1024, true); |
||||
ERROR: pglz_decompress failed |
||||
-- Corrupted compressed data. Set control bit with match tag where length |
||||
-- nibble is 3 bytes (extended length), no data follows. |
||||
SELECT test_pglz_decompress('\x010f01'::bytea, 1024, false); |
||||
ERROR: pglz_decompress failed |
||||
SELECT test_pglz_decompress('\x010f01'::bytea, 1024, true); |
||||
ERROR: pglz_decompress failed |
||||
-- Clean up |
||||
DROP FUNCTION test_pglz_compress; |
||||
DROP FUNCTION test_pglz_decompress; |
||||
@ -0,0 +1,53 @@ |
||||
-- |
||||
-- Tests for PGLZ compression |
||||
-- |
||||
|
||||
-- directory paths and dlsuffix are passed to us in environment variables |
||||
\getenv libdir PG_LIBDIR |
||||
\getenv dlsuffix PG_DLSUFFIX |
||||
|
||||
\set regresslib :libdir '/regress' :dlsuffix |
||||
|
||||
CREATE FUNCTION test_pglz_compress(bytea) |
||||
RETURNS bytea |
||||
AS :'regresslib' LANGUAGE C STRICT; |
||||
CREATE FUNCTION test_pglz_decompress(bytea, int4, bool) |
||||
RETURNS bytea |
||||
AS :'regresslib' LANGUAGE C STRICT; |
||||
|
||||
-- Round-trip with pglz: compress then decompress. |
||||
SELECT test_pglz_decompress(test_pglz_compress( |
||||
decode(repeat('abcd', 100), 'escape')), 400, false) = |
||||
decode(repeat('abcd', 100), 'escape') AS roundtrip_ok; |
||||
SELECT test_pglz_decompress(test_pglz_compress( |
||||
decode(repeat('abcd', 100), 'escape')), 400, true) = |
||||
decode(repeat('abcd', 100), 'escape') AS roundtrip_ok; |
||||
|
||||
-- Decompression with rawsize too large, fails to fill the destination |
||||
-- buffer. |
||||
SELECT test_pglz_decompress(test_pglz_compress( |
||||
decode(repeat('abcd', 100), 'escape')), 500, true); |
||||
|
||||
-- Decompression with rawsize too small, fails with source not fully |
||||
-- consumed. |
||||
SELECT test_pglz_decompress(test_pglz_compress( |
||||
decode(repeat('abcd', 100), 'escape')), 100, true); |
||||
|
||||
-- Corrupted compressed data. Set control bit with read of a match tag, |
||||
-- no data follows. |
||||
SELECT length(test_pglz_decompress('\x01'::bytea, 1024, false)) AS ctrl_only_len; |
||||
SELECT test_pglz_decompress('\x01'::bytea, 1024, true); |
||||
|
||||
-- Corrupted compressed data. Set control bit with read of a match tag, |
||||
-- 1 byte follows. |
||||
SELECT test_pglz_decompress('\x01ff'::bytea, 1024, false); |
||||
SELECT test_pglz_decompress('\x01ff'::bytea, 1024, true); |
||||
|
||||
-- Corrupted compressed data. Set control bit with match tag where length |
||||
-- nibble is 3 bytes (extended length), no data follows. |
||||
SELECT test_pglz_decompress('\x010f01'::bytea, 1024, false); |
||||
SELECT test_pglz_decompress('\x010f01'::bytea, 1024, true); |
||||
|
||||
-- Clean up |
||||
DROP FUNCTION test_pglz_compress; |
||||
DROP FUNCTION test_pglz_decompress; |
||||
Loading…
Reference in new issue