Properly determine length for on-disk TOAST values
authorTomas Vondra <tomas.vondra@postgresql.org>
Sat, 16 Nov 2019 01:40:02 +0000 (02:40 +0100)
committerTomas Vondra <tomas.vondra@postgresql.org>
Sat, 16 Nov 2019 02:07:11 +0000 (03:07 +0100)
In detoast_attr_slice, VARSIZE_ANY was used to compute compressed length
of on-disk TOAST values. That's incorrect, because the varlena value may
be just a TOAST pointer, producing either bogus value or crashing.

This is likely why the code was crashing on big-endian machines before
540f31680913 replaced the VARSIZE with VARSIZE_ANY, which however only
masked the issue.

Reported-by: Rushabh Lathia
Discussion: https://postgr.es/m/CAL-OGkthU9Gs7TZchf5OWaL-Gsi=hXqufTxKv9qpNG73d5na_g@mail.gmail.com

src/backend/access/common/detoast.c

index f752ac7bbc917c1220eb764da6378a550d493b9d..8c89fc2a558bd6e199f92da55dec617fef9de403 100644 (file)
@@ -233,7 +233,7 @@ detoast_attr_slice(struct varlena *attr,
             * of a given length (after decompression).
             */
            max_size = pglz_maximum_compressed_size(sliceoffset + slicelength,
-                                                   TOAST_COMPRESS_SIZE(attr));
+                                                   toast_pointer.va_extsize);
 
            /*
             * Fetch enough compressed slices (compressed marker will get set