@ -166,7 +166,7 @@
*
* Copyright ( c ) 1999 - 2008 , PostgreSQL Global Development Group
*
* $ PostgreSQL : pgsql / src / backend / utils / adt / pg_lzcompress . c , v 1.29 2008 / 01 / 01 19 : 45 : 52 momjian Exp $
* $ PostgreSQL : pgsql / src / backend / utils / adt / pg_lzcompress . c , v 1.29 .2 .1 2008 / 05 / 28 21 : 58 : 03 tgl Exp $
* - - - - - - - - - -
*/
# include "postgres.h"
@ -631,26 +631,26 @@ pglz_compress(const char *source, int32 slen, PGLZ_Header *dest,
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 ;
const unsigned char * sp ;
const unsigned char * srcend ;
unsigned char * dp ;
unsigned char * destend ;
while ( dp < dend )
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 .
* Read one control byte and process the next 8 items ( or as many
* as remain in the compressed input ) .
*/
ctrl = * dp + + ;
for ( ctrlc = 0 ; ctrlc < 8 & & dp < dend ; ctrlc + + )
unsigned char ctrl = * sp + + ;
int ctrlc ;
for ( ctrlc = 0 ; ctrlc < 8 & & sp < srcend ; ctrlc + + )
{
if ( ctrl & 1 )
{
@ -661,11 +661,27 @@ pglz_decompress(const PGLZ_Header *source, char *dest)
* 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 ;
int32 len ;
int32 off ;
len = ( sp [ 0 ] & 0x0f ) + 3 ;
off = ( ( sp [ 0 ] & 0xf0 ) < < 4 ) | sp [ 1 ] ;
sp + = 2 ;
if ( len = = 18 )
len + = * dp + + ;
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
@ -675,8 +691,8 @@ pglz_decompress(const PGLZ_Header *source, char *dest)
*/
while ( len - - )
{
* bp = b p[ - off ] ;
b p+ + ;
* dp = d p[ - off ] ;
d p+ + ;
}
}
else
@ -685,7 +701,10 @@ pglz_decompress(const PGLZ_Header *source, char *dest)
* An unset control bit means LITERAL BYTE . So we just copy
* one from INPUT to OUTPUT .
*/
* bp + + = * dp + + ;
if ( dp > = destend ) /* check for buffer overrun */
break ; /* do not clobber memory */
* dp + + = * sp + + ;
}
/*
@ -696,14 +715,10 @@ pglz_decompress(const PGLZ_Header *source, char *dest)
}
/*
* 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 ) .
* Check we decompressed the right amount .
*/
destsize = ( char * ) bp - dest ;
if ( destsize ! = source - > rawsize )
elog ( destsize > source - > rawsize ? FATAL : ERROR ,
" compressed data is corrupt " ) ;
if ( dp ! = destend | | sp ! = srcend )
elog ( ERROR , " compressed data is corrupt " ) ;
/*
* That ' s it .