@ -210,11 +210,8 @@ heap_page_items(PG_FUNCTION_ARGS)
lp_offset + lp_len < = raw_page_size )
lp_offset + lp_len < = raw_page_size )
{
{
HeapTupleHeader tuphdr ;
HeapTupleHeader tuphdr ;
bytea * tuple_data_bytea ;
int tuple_data_len ;
/* Extract information from the tuple header */
/* Extract information from the tuple header */
tuphdr = ( HeapTupleHeader ) PageGetItem ( page , id ) ;
tuphdr = ( HeapTupleHeader ) PageGetItem ( page , id ) ;
values [ 4 ] = UInt32GetDatum ( HeapTupleHeaderGetRawXmin ( tuphdr ) ) ;
values [ 4 ] = UInt32GetDatum ( HeapTupleHeaderGetRawXmin ( tuphdr ) ) ;
@ -226,31 +223,32 @@ heap_page_items(PG_FUNCTION_ARGS)
values [ 9 ] = UInt32GetDatum ( tuphdr - > t_infomask ) ;
values [ 9 ] = UInt32GetDatum ( tuphdr - > t_infomask ) ;
values [ 10 ] = UInt8GetDatum ( tuphdr - > t_hoff ) ;
values [ 10 ] = UInt8GetDatum ( tuphdr - > t_hoff ) ;
/* Copy raw tuple data into bytea attribute */
tuple_data_len = lp_len - tuphdr - > t_hoff ;
tuple_data_bytea = ( bytea * ) palloc ( tuple_data_len + VARHDRSZ ) ;
SET_VARSIZE ( tuple_data_bytea , tuple_data_len + VARHDRSZ ) ;
memcpy ( VARDATA ( tuple_data_bytea ) , ( char * ) tuphdr + tuphdr - > t_hoff ,
tuple_data_len ) ;
values [ 13 ] = PointerGetDatum ( tuple_data_bytea ) ;
/*
/*
* We already checked that the item is completely within the raw
* We already checked that the item is completely within the raw
* page passed to us , with the length given in the line pointer .
* page passed to us , with the length given in the line pointer .
* Let ' s check that t_hoff doesn ' t point over lp_len , before using
* But t_hoff could be out of range , so check it before relying on
* it to access t_bits and oid .
* it to fetch additional info .
*/
*/
if ( tuphdr - > t_hoff > = SizeofHeapTupleHeader & &
if ( tuphdr - > t_hoff > = SizeofHeapTupleHeader & &
tuphdr - > t_hoff < = lp_len & &
tuphdr - > t_hoff < = lp_len & &
tuphdr - > t_hoff = = MAXALIGN ( tuphdr - > t_hoff ) )
tuphdr - > t_hoff = = MAXALIGN ( tuphdr - > t_hoff ) )
{
{
int tuple_data_len ;
bytea * tuple_data_bytea ;
/* Copy null bitmask and OID, if present */
if ( tuphdr - > t_infomask & HEAP_HASNULL )
if ( tuphdr - > t_infomask & HEAP_HASNULL )
{
{
int bits_len ;
int bitmaplen ;
bits_len =
bitmaplen = BITMAPLEN ( HeapTupleHeaderGetNatts ( tuphdr ) ) ;
BITMAPLEN ( HeapTupleHeaderGetNatts ( tuphdr ) ) * BITS_PER_BYTE ;
/* better range-check the attribute count, too */
values [ 11 ] = CStringGetTextDatum ( bits_to_text ( tuphdr - > t_bits , bits_len ) ) ;
if ( bitmaplen < = tuphdr - > t_hoff - SizeofHeapTupleHeader )
values [ 11 ] =
CStringGetTextDatum ( bits_to_text ( tuphdr - > t_bits ,
bitmaplen * BITS_PER_BYTE ) ) ;
else
nulls [ 11 ] = true ;
}
}
else
else
nulls [ 11 ] = true ;
nulls [ 11 ] = true ;
@ -259,11 +257,22 @@ heap_page_items(PG_FUNCTION_ARGS)
values [ 12 ] = HeapTupleHeaderGetOidOld ( tuphdr ) ;
values [ 12 ] = HeapTupleHeaderGetOidOld ( tuphdr ) ;
else
else
nulls [ 12 ] = true ;
nulls [ 12 ] = true ;
/* Copy raw tuple data into bytea attribute */
tuple_data_len = lp_len - tuphdr - > t_hoff ;
tuple_data_bytea = ( bytea * ) palloc ( tuple_data_len + VARHDRSZ ) ;
SET_VARSIZE ( tuple_data_bytea , tuple_data_len + VARHDRSZ ) ;
if ( tuple_data_len > 0 )
memcpy ( VARDATA ( tuple_data_bytea ) ,
( char * ) tuphdr + tuphdr - > t_hoff ,
tuple_data_len ) ;
values [ 13 ] = PointerGetDatum ( tuple_data_bytea ) ;
}
}
else
else
{
{
nulls [ 11 ] = true ;
nulls [ 11 ] = true ;
nulls [ 12 ] = true ;
nulls [ 12 ] = true ;
nulls [ 13 ] = true ;
}
}
}
}
else
else