diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c
index e488528efbea69a065124bd0dcf3a93ef26d7a39..f8a7b0cd5693fbdb60ae70b2a9fc412c00e349a9 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -171,13 +171,38 @@ myLargeObjectExists(Oid loid, Snapshot snapshot)
 }
 
 
-static int32
-getbytealen(bytea *data)
+/*
+ * Extract data field from a pg_largeobject tuple, detoasting if needed
+ * and verifying that the length is sane.  Returns data pointer (a bytea *),
+ * data length, and an indication of whether to pfree the data pointer.
+ */
+static void
+getdatafield(Form_pg_largeobject tuple,
+			 bytea **pdatafield,
+			 int *plen,
+			 bool *pfreeit)
 {
-	Assert(!VARATT_IS_EXTENDED(data));
-	if (VARSIZE(data) < VARHDRSZ)
-		elog(ERROR, "invalid VARSIZE(data)");
-	return (VARSIZE(data) - VARHDRSZ);
+	bytea	   *datafield;
+	int			len;
+	bool		freeit;
+
+	datafield = &(tuple->data); /* see note at top of file */
+	freeit = false;
+	if (VARATT_IS_EXTENDED(datafield))
+	{
+		datafield = (bytea *)
+			heap_tuple_untoast_attr((struct varlena *) datafield);
+		freeit = true;
+	}
+	len = VARSIZE(datafield) - VARHDRSZ;
+	if (len < 0 || len > LOBLKSIZE)
+		ereport(ERROR,
+				(errcode(ERRCODE_DATA_CORRUPTED),
+				 errmsg("pg_largeobject entry for OID %u, page %d has invalid data field size %d",
+						tuple->loid, tuple->pageno, len)));
+	*pdatafield = datafield;
+	*plen = len;
+	*pfreeit = freeit;
 }
 
 
@@ -363,20 +388,14 @@ inv_getsize(LargeObjectDesc *obj_desc)
 	{
 		Form_pg_largeobject data;
 		bytea	   *datafield;
+		int			len;
 		bool		pfreeit;
 
 		if (HeapTupleHasNulls(tuple))	/* paranoia */
 			elog(ERROR, "null field found in pg_largeobject");
 		data = (Form_pg_largeobject) GETSTRUCT(tuple);
-		datafield = &(data->data);		/* see note at top of file */
-		pfreeit = false;
-		if (VARATT_IS_EXTENDED(datafield))
-		{
-			datafield = (bytea *)
-				heap_tuple_untoast_attr((struct varlena *) datafield);
-			pfreeit = true;
-		}
-		lastbyte = data->pageno * LOBLKSIZE + getbytealen(datafield);
+		getdatafield(data, &datafield, &len, &pfreeit);
+		lastbyte = data->pageno * LOBLKSIZE + len;
 		if (pfreeit)
 			pfree(datafield);
 	}
@@ -491,15 +510,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
 			off = (int) (obj_desc->offset - pageoff);
 			Assert(off >= 0 && off < LOBLKSIZE);
 
-			datafield = &(data->data);	/* see note at top of file */
-			pfreeit = false;
-			if (VARATT_IS_EXTENDED(datafield))
-			{
-				datafield = (bytea *)
-					heap_tuple_untoast_attr((struct varlena *) datafield);
-				pfreeit = true;
-			}
-			len = getbytealen(datafield);
+			getdatafield(data, &datafield, &len, &pfreeit);
 			if (len > off)
 			{
 				n = len - off;
@@ -618,16 +629,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
 			 *
 			 * First, load old data into workbuf
 			 */
-			datafield = &(olddata->data);		/* see note at top of file */
-			pfreeit = false;
-			if (VARATT_IS_EXTENDED(datafield))
-			{
-				datafield = (bytea *)
-					heap_tuple_untoast_attr((struct varlena *) datafield);
-				pfreeit = true;
-			}
-			len = getbytealen(datafield);
-			Assert(len <= LOBLKSIZE);
+			getdatafield(olddata, &datafield, &len, &pfreeit);
 			memcpy(workb, VARDATA(datafield), len);
 			if (pfreeit)
 				pfree(datafield);
@@ -803,19 +805,11 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
 	if (olddata != NULL && olddata->pageno == pageno)
 	{
 		/* First, load old data into workbuf */
-		bytea	   *datafield = &(olddata->data);		/* see note at top of
-														 * file */
-		bool		pfreeit = false;
+		bytea	   *datafield;
 		int			pagelen;
+		bool		pfreeit;
 
-		if (VARATT_IS_EXTENDED(datafield))
-		{
-			datafield = (bytea *)
-				heap_tuple_untoast_attr((struct varlena *) datafield);
-			pfreeit = true;
-		}
-		pagelen = getbytealen(datafield);
-		Assert(pagelen <= LOBLKSIZE);
+		getdatafield(olddata, &datafield, &pagelen, &pfreeit);
 		memcpy(workb, VARDATA(datafield), pagelen);
 		if (pfreeit)
 			pfree(datafield);