Fix various instances of undefined behavior

Mostly this involves checking for NULL pointer before doing operations
that add a non-zero offset.

The exception is an overflow warning in heap_fetch_toast_slice(). This
was caused by unneeded parentheses forcing an expression to be
evaluated to a negative integer, which then got cast to size_t.

Per clang 21 undefined behavior sanitizer.

Backpatch to all supported versions.

Co-authored-by: Alexander Lakhin <exclusion@gmail.com>
Reported-by: Alexander Lakhin <exclusion@gmail.com>
Discussion: https://postgr.es/m/777bd201-6e3a-4da0-a922-4ea9de46a3ee@gmail.com
Backpatch-through: 14
REL_16_STABLE
John Naylor 24 hours ago
parent 6548e4a10d
commit 73ac2b3740
  1. 5
      contrib/pg_trgm/trgm_gist.c
  2. 2
      src/backend/access/heap/heaptoast.c
  3. 5
      src/backend/utils/adt/multirangetypes.c
  4. 3
      src/backend/utils/sort/sharedtuplestore.c

@ -699,10 +699,13 @@ gtrgm_penalty(PG_FUNCTION_ARGS)
if (ISARRKEY(newval))
{
char *cache = (char *) fcinfo->flinfo->fn_extra;
TRGM *cachedVal = (TRGM *) (cache + MAXALIGN(siglen));
TRGM *cachedVal = NULL;
Size newvalsize = VARSIZE(newval);
BITVECP sign;
if (cache != NULL)
cachedVal = (TRGM *) (cache + MAXALIGN(siglen));
/*
* Cache the sign data across multiple calls with the same newval.
*/

@ -770,7 +770,7 @@ heap_fetch_toast_slice(Relation toastrel, Oid valueid, int32 attrsize,
chcpyend = (sliceoffset + slicelength - 1) % TOAST_MAX_CHUNK_SIZE;
memcpy(VARDATA(result) +
(curchunk * TOAST_MAX_CHUNK_SIZE - sliceoffset) + chcpystrt,
curchunk * TOAST_MAX_CHUNK_SIZE - sliceoffset + chcpystrt,
chunkdata + chcpystrt,
(chcpyend - chcpystrt) + 1);

@ -484,8 +484,9 @@ multirange_canonicalize(TypeCacheEntry *rangetyp, int32 input_range_count,
int32 output_range_count = 0;
/* Sort the ranges so we can find the ones that overlap/meet. */
qsort_arg(ranges, input_range_count, sizeof(RangeType *), range_compare,
rangetyp);
if (ranges != NULL)
qsort_arg(ranges, input_range_count, sizeof(RangeType *),
range_compare, rangetyp);
/* Now merge where possible: */
for (i = 0; i < input_range_count; i++)

@ -325,7 +325,8 @@ sts_puttuple(SharedTuplestoreAccessor *accessor, void *meta_data,
/* Do we have space? */
size = accessor->sts->meta_data_size + tuple->t_len;
if (accessor->write_pointer + size > accessor->write_end)
if (accessor->write_pointer == NULL ||
accessor->write_pointer + size > accessor->write_end)
{
if (accessor->write_chunk == NULL)
{

Loading…
Cancel
Save