I attached backported pg_lzcompress patch which is already in head for version
8.2 and 8.3.
Version 8.1 and prior contains more changes in decompress code and they does not
contain any check. Shell I backported it as well or it will be better to keep it
untouched?
Zdenek
*** src/backend/utils/adt/pg_lzcompress.c 2006/10/05 23:33:33 1.23
--- src/backend/utils/adt/pg_lzcompress.c 2008/03/08 01:09:36 1.31
*** pglz_compress(const char *source, int32
*** 631,656
void
pglz_decompress(const PGLZ_Header *source, char *dest)
{
! const unsigned char *dp;
! const unsigned char *dend;
! unsigned char *bp;
! unsigned char ctrl;
! int32 ctrlc;
! int32 len;
! int32 off;
! int32 destsize;
!
! dp = ((const unsigned char *) source) + sizeof(PGLZ_Header);
! dend = ((const unsigned char *) source) + VARATT_SIZE(source);
! bp = (unsigned char *) dest;
! while (dp < dend)
{
/*
!* Read one control byte and process the next 8 items.
*/
! ctrl = *dp++;
! for (ctrlc = 0; ctrlc < 8 && dp < dend; ctrlc++)
{
if (ctrl & 1)
{
--- 641,666
void
pglz_decompress(const PGLZ_Header *source, char *dest)
{
! const unsigned char *sp;
! const unsigned char *srcend;
! unsigned char *dp;
! unsigned char *destend;
!
! sp = ((const unsigned char *) source) + sizeof(PGLZ_Header);
! srcend = ((const unsigned char *) source) + VARATT_SIZE(source);
! dp = (unsigned char *) dest;
! destend = dp + source->rawsize;
! while (sp < srcend && dp < destend)
{
/*
!* Read one control byte and process the next 8 items (or as
many
!* as remain in the compressed input).
*/
! unsigned char ctrl = *sp++;
! int ctrlc;
!
! for (ctrlc = 0; ctrlc < 8 && sp < srcend; ctrlc++)
{
if (ctrl & 1)
{
*** pglz_decompress(const PGLZ_Header *sourc
*** 661,671
* coded as 18, another extension tag byte
tells how much
* longer the match really was (0-255).
*/
! len = (dp[0] & 0x0f) + 3;
! off = ((dp[0] & 0xf0) << 4) | dp[1];
! dp += 2;
if (len == 18)
! len += *dp++;
/*
* Now we copy the bytes specified by the tag
from OUTPUT to
--- 671,697
* coded as 18, another extension tag byte
tells how much
* longer the match really was (0-255).
*/
! int32 len;
! int32 off;
!
! len = (sp[0] & 0x0f) + 3;
! off = ((sp[0] & 0xf0) << 4) | sp[1];
! sp += 2;
if (len == 18)
! len += *sp++;
!
! /*
!* Check for output buffer overrun, to ensure
we don't
!* clobber memory in case of corrupt input.
Note: we must
!* advance dp here to ensure the error is
detected below
!* the loop. We don't simply put the elog
inside the loop
!* since that will probably interfere with
optimization.
!*/
! if (dp + len > destend)
! {
! dp += len;
! break;
! }
/*
* Now we copy the bytes specified by the tag
from OUTPUT to
*** pglz_decompress(const PGLZ_Header *sourc
*** 675,682
*/
while (len--)
{
! *bp = bp[-off];
! bp++;
}
}
else
--- 701,708
*/
while (len--)
{
! *dp = dp[-off];
!