diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2020-11-02 11:25:18 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2020-11-02 11:25:18 -0500 |
commit | 7957e75c588c0b17210d4379afb50ea2673b0d20 (patch) | |
tree | d02a815b2aa9e5d2a59b7e16e184cf4d80f54c7d | |
parent | 57fae192f8f7d094159c913f10fcfd11cd827332 (diff) | |
download | postgresql-7957e75c588c0b17210d4379afb50ea2673b0d20.tar.gz postgresql-7957e75c588c0b17210d4379afb50ea2673b0d20.zip |
Second thoughts on TOAST decompression.
On detecting a corrupted match tag, pglz_decompress() should just
summarily return -1. Breaking out of the loop, as I did in dfc797730,
doesn't quite guarantee that will happen. Also, we can use
unlikely() on that check, just in case it helps.
Backpatch to v13, like the previous patch.
-rw-r--r-- | src/common/pg_lzcompress.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/src/common/pg_lzcompress.c b/src/common/pg_lzcompress.c index 79747767ce0..f9c29820e30 100644 --- a/src/common/pg_lzcompress.c +++ b/src/common/pg_lzcompress.c @@ -680,9 +680,12 @@ pglz_compress(const char *source, int32 slen, char *dest, * pglz_decompress - * * Decompresses source into dest. Returns the number of bytes - * decompressed in the destination buffer, and *optionally* - * checks that both the source and dest buffers have been - * fully read and written to, respectively. + * decompressed into the destination buffer, or -1 if the + * compressed data is corrupted. + * + * If check_complete is true, the data is considered corrupted + * if we don't exactly fill the destination buffer. Callers that + * are extracting a slice typically can't apply this check. * ---------- */ int32 @@ -736,8 +739,8 @@ pglz_decompress(const char *source, int32 slen, char *dest, * must check this, else we risk an infinite loop below in the * face of corrupt data.) */ - if (sp > srcend || off == 0) - break; + if (unlikely(sp > srcend || off == 0)) + return -1; /* * Don't emit more data than requested. @@ -809,9 +812,7 @@ pglz_decompress(const char *source, int32 slen, char *dest, } /* - * Check we decompressed the right amount. If we are slicing, then we - * won't necessarily be at the end of the source or dest buffers when we - * hit a stop, so we don't test them. + * If requested, check we decompressed the right amount. */ if (check_complete && (dp != destend || sp != srcend)) return -1; |