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];
!                                       dp++;
                                }
                        }
                        else
*************** pglz_decompress(const PGLZ_Header *sourc
*** 685,691 ****
                                 * An unset control bit means LITERAL BYTE. So 
we just copy
                                 * one from INPUT to OUTPUT.
                                 */
!                               *bp++ = *dp++;
                        }
  
                        /*
--- 711,720 ----
                                 * An unset control bit means LITERAL BYTE. So 
we just copy
                                 * one from INPUT to OUTPUT.
                                 */
!                               if (dp >= destend)      /* check for buffer 
overrun */
!                                       break;                  /* do not 
clobber memory */
! 
!                               *dp++ = *sp++;
                        }
  
                        /*
*************** pglz_decompress(const PGLZ_Header *sourc
*** 696,709 ****
        }
  
        /*
!        * Check we decompressed the right amount, else die.  This is a FATAL
!        * condition if we tromped on more memory than expected (we assume we
!        * have not tromped on shared memory, though, so need not PANIC).
!        */
!       destsize = (char *) bp - dest;
!       if (destsize != source->rawsize)
!               elog(destsize > source->rawsize ? FATAL : ERROR,
!                        "compressed data is corrupt");
  
        /*
         * That's it.
--- 725,734 ----
        }
  
        /*
!        * Check we decompressed the right amount.
!        */
!       if (dp != destend || sp != srcend)
!               elog(ERROR, "compressed data is corrupt");
  
        /*
         * That's it.
*** src/backend/utils/adt/pg_lzcompress.c       2008/01/01 19:45:52     1.29
--- 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) + VARSIZE(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) + VARSIZE(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];
!                                       dp++;
                                }
                        }
                        else
*************** pglz_decompress(const PGLZ_Header *sourc
*** 685,691 ****
                                 * An unset control bit means LITERAL BYTE. So 
we just copy
                                 * one from INPUT to OUTPUT.
                                 */
!                               *bp++ = *dp++;
                        }
  
                        /*
--- 711,720 ----
                                 * An unset control bit means LITERAL BYTE. So 
we just copy
                                 * one from INPUT to OUTPUT.
                                 */
!                               if (dp >= destend)      /* check for buffer 
overrun */
!                                       break;                  /* do not 
clobber memory */
! 
!                               *dp++ = *sp++;
                        }
  
                        /*
*************** pglz_decompress(const PGLZ_Header *sourc
*** 696,709 ****
        }
  
        /*
!        * Check we decompressed the right amount, else die.  This is a FATAL
!        * condition if we tromped on more memory than expected (we assume we 
have
!        * not tromped on shared memory, though, so need not PANIC).
!        */
!       destsize = (char *) bp - dest;
!       if (destsize != source->rawsize)
!               elog(destsize > source->rawsize ? FATAL : ERROR,
!                        "compressed data is corrupt");
  
        /*
         * That's it.
--- 725,734 ----
        }
  
        /*
!        * Check we decompressed the right amount.
!        */
!       if (dp != destend || sp != srcend)
!               elog(ERROR, "compressed data is corrupt");
  
        /*
         * That's it.
-- 
Sent via pgsql-patches mailing list (pgsql-patches@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-patches

Reply via email to