diff --git a/src/backend/access/gin/ginpostinglist.c b/src/backend/access/gin/ginpostinglist.c index 9d68a980722f266242afe004ccdc76e1054785fc..81bbb09c24462ec0c58fa241b8f65bbcc7150d46 100644 --- a/src/backend/access/gin/ginpostinglist.c +++ b/src/backend/access/gin/ginpostinglist.c @@ -176,6 +176,9 @@ decode_varbyte(unsigned char **ptr) * 'maxsize' bytes in size. The number items in the returned segment is * returned in *nwritten. If it's not equal to nipd, not all the items fit * in 'maxsize', and only the first *nwritten were encoded. + * + * The allocated size of the returned struct is short-aligned, and the padding + * byte at the end, if any, is zero. */ GinPostingList * ginCompressPostingList(const ItemPointer ipd, int nipd, int maxsize, @@ -188,9 +191,12 @@ ginCompressPostingList(const ItemPointer ipd, int nipd, int maxsize, unsigned char *ptr; unsigned char *endptr; + maxsize = SHORTALIGN_DOWN(maxsize); + result = palloc(maxsize); maxbytes = maxsize - offsetof(GinPostingList, bytes); + Assert(maxbytes > 0); /* Store the first special item */ result->first = ipd[0]; @@ -228,6 +234,13 @@ ginCompressPostingList(const ItemPointer ipd, int nipd, int maxsize, } result->nbytes = ptr - result->bytes; + /* + * If we wrote an odd number of bytes, zero out the padding byte at the + * end. + */ + if (result->nbytes != SHORTALIGN(result->nbytes)) + result->bytes[result->nbytes] = 0; + if (nwritten) *nwritten = totalpacked;