Add some simple defenses against null fields in pg_largeobject, and add
comments noting that there's an alignment assumption now that the data field could be in 1-byte-header format. Per discussion with Greg Stark.
This commit is contained in:
parent
ee0d34ab64
commit
e976fd43c6
@ -5,6 +5,13 @@
|
||||
* contains the user-level large object application interface routines.
|
||||
*
|
||||
*
|
||||
* Note: we access pg_largeobject.data using its C struct declaration.
|
||||
* This is safe because it immediately follows pageno which is an int4 field,
|
||||
* and therefore the data field will always be 4-byte aligned, even if it
|
||||
* is in the short 1-byte-header format. We have to detoast it since it's
|
||||
* quite likely to be in compressed or short format. We also need to check
|
||||
* for NULLs, since initdb will mark loid and pageno but not data as NOT NULL.
|
||||
*
|
||||
* Note: many of these routines leak memory in CurrentMemoryContext, as indeed
|
||||
* does most of the backend code. We expect that CurrentMemoryContext will
|
||||
* be a short-lived context. Data that must persist across function calls
|
||||
@ -17,7 +24,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.124 2007/04/06 04:21:42 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/storage/large_object/inv_api.c,v 1.125 2007/06/12 19:46:24 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -330,8 +337,10 @@ inv_getsize(LargeObjectDesc *obj_desc)
|
||||
bool pfreeit;
|
||||
|
||||
found = true;
|
||||
if (HeapTupleHasNulls(tuple)) /* paranoia */
|
||||
elog(ERROR, "null field found in pg_largeobject");
|
||||
data = (Form_pg_largeobject) GETSTRUCT(tuple);
|
||||
datafield = &(data->data);
|
||||
datafield = &(data->data); /* see note at top of file */
|
||||
pfreeit = false;
|
||||
if (VARATT_IS_EXTENDED(datafield))
|
||||
{
|
||||
@ -434,6 +443,8 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
||||
bytea *datafield;
|
||||
bool pfreeit;
|
||||
|
||||
if (HeapTupleHasNulls(tuple)) /* paranoia */
|
||||
elog(ERROR, "null field found in pg_largeobject");
|
||||
data = (Form_pg_largeobject) GETSTRUCT(tuple);
|
||||
|
||||
/*
|
||||
@ -457,7 +468,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
|
||||
off = (int) (obj_desc->offset - pageoff);
|
||||
Assert(off >= 0 && off < LOBLKSIZE);
|
||||
|
||||
datafield = &(data->data);
|
||||
datafield = &(data->data); /* see note at top of file */
|
||||
pfreeit = false;
|
||||
if (VARATT_IS_EXTENDED(datafield))
|
||||
{
|
||||
@ -558,6 +569,8 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
|
||||
{
|
||||
if ((oldtuple = index_getnext(sd, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
if (HeapTupleHasNulls(oldtuple)) /* paranoia */
|
||||
elog(ERROR, "null field found in pg_largeobject");
|
||||
olddata = (Form_pg_largeobject) GETSTRUCT(oldtuple);
|
||||
Assert(olddata->pageno >= pageno);
|
||||
}
|
||||
@ -575,7 +588,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
|
||||
*
|
||||
* First, load old data into workbuf
|
||||
*/
|
||||
datafield = &(olddata->data);
|
||||
datafield = &(olddata->data); /* see note at top of file */
|
||||
pfreeit = false;
|
||||
if (VARATT_IS_EXTENDED(datafield))
|
||||
{
|
||||
@ -737,6 +750,8 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
|
||||
olddata = NULL;
|
||||
if ((oldtuple = index_getnext(sd, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
if (HeapTupleHasNulls(oldtuple)) /* paranoia */
|
||||
elog(ERROR, "null field found in pg_largeobject");
|
||||
olddata = (Form_pg_largeobject) GETSTRUCT(oldtuple);
|
||||
Assert(olddata->pageno >= pageno);
|
||||
}
|
||||
@ -749,7 +764,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
|
||||
if (olddata != NULL && olddata->pageno == pageno)
|
||||
{
|
||||
/* First, load old data into workbuf */
|
||||
bytea *datafield = &(olddata->data);
|
||||
bytea *datafield = &(olddata->data); /* see note at top of file */
|
||||
bool pfreeit = false;
|
||||
int pagelen;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user