pg_lzcompress patch for 8.3, 8.2 branch

Zdenek Kotala <[email protected]>
Newsgroups gmane.comp.db.postgresql.devel.patches
Message-ID <[email protected]>
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


-- 
Sent via pgsql-patches mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-patches
pg_lzcompress.patch.82 (text/plain, 4.1 KB)
*** 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.
pg_lzcompress.patch.83 (text/plain, 4.1 KB)
*** 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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.