agora inbox for pgsql-hackers@postgresql.org
help / color / mirror / Atom feedFrom: Mats Kindahl <mats@timescale.com>
Subject: [PATCH v3 2/2] Ensure comparison functions are transitive
Date: Tue, 6 Feb 2024 14:53:53 +0100
There are a few comparison functions to qsort() that are non-transitive
because they can cause an overflow. Fix these functions to instead use
normal comparisons and return -1, 0, or 1 explicitly.
---
src/backend/access/spgist/spgtextproc.c | 2 +-
src/backend/utils/cache/relcache.c | 9 ++++++---
src/bin/pg_upgrade/function.c | 10 ++++++----
src/bin/psql/crosstabview.c | 5 ++++-
4 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/src/backend/access/spgist/spgtextproc.c b/src/backend/access/spgist/spgtextproc.c
index b8fd0c2ad8..e561bde63e 100644
--- a/src/backend/access/spgist/spgtextproc.c
+++ b/src/backend/access/spgist/spgtextproc.c
@@ -325,7 +325,7 @@ cmpNodePtr(const void *a, const void *b)
const spgNodePtr *aa = (const spgNodePtr *) a;
const spgNodePtr *bb = (const spgNodePtr *) b;
- return aa->c - bb->c;
+ return (aa->c > bb->c) - (aa->c < bb->c);
}
Datum
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index ac106b40e3..54682a0e60 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -4517,10 +4517,13 @@ AttrDefaultFetch(Relation relation, int ndef)
static int
AttrDefaultCmp(const void *a, const void *b)
{
- const AttrDefault *ada = (const AttrDefault *) a;
- const AttrDefault *adb = (const AttrDefault *) b;
+ AttrNumber ana = ((const AttrDefault *) a)->adnum;
+ AttrNumber anb = ((const AttrDefault *) b)->adnum;
- return ada->adnum - adb->adnum;
+ /* ensure upcasting approach is transitive */
+ Assert(sizeof(AttrNumber) == 2);
+
+ return (int) ana - (int) anb;
}
/*
diff --git a/src/bin/pg_upgrade/function.c b/src/bin/pg_upgrade/function.c
index af998f74d3..b421500bbb 100644
--- a/src/bin/pg_upgrade/function.c
+++ b/src/bin/pg_upgrade/function.c
@@ -32,14 +32,16 @@ library_name_compare(const void *p1, const void *p2)
int slen1 = strlen(str1);
int slen2 = strlen(str2);
int cmp = strcmp(str1, str2);
+ int p1db = ((const LibraryInfo *) p1)->dbnum;
+ int p2db = ((const LibraryInfo *) p2)->dbnum;
if (slen1 != slen2)
- return slen1 - slen2;
+ return (slen1 > slen2) - (slen1 < slen2);
+
if (cmp != 0)
return cmp;
- else
- return ((const LibraryInfo *) p1)->dbnum -
- ((const LibraryInfo *) p2)->dbnum;
+
+ return (p1db > p2db) - (p1db < p2db);
}
diff --git a/src/bin/psql/crosstabview.c b/src/bin/psql/crosstabview.c
index c6116b7238..7660f0ed4b 100644
--- a/src/bin/psql/crosstabview.c
+++ b/src/bin/psql/crosstabview.c
@@ -709,5 +709,8 @@ pivotFieldCompare(const void *a, const void *b)
static int
rankCompare(const void *a, const void *b)
{
- return *((const int *) a) - *((const int *) b);
+ const int an = *(const int *) a;
+ const int bn = *(const int *) b;
+
+ return (an > bn) - (an < bn);
}
--
2.25.1
--T4sUOijqQbZv57TR--
view thread (209+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: mats@timescale.com
Subject: Re: [PATCH v3 2/2] Ensure comparison functions are transitive
In-Reply-To: <no-message-id-1004173@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox