pgsql: Fix bogus casting in BlockIdGetBlockNumber().

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-committers(at)lists(dot)postgresql(dot)org
Subject: pgsql: Fix bogus casting in BlockIdGetBlockNumber().
Date: 2022-03-04 00:04:25
Message-ID: E1nPvQm-000nMs-N3@gemulon.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-committers

Fix bogus casting in BlockIdGetBlockNumber().

This macro cast the result to BlockNumber after shifting, not before,
which is the wrong thing. Per the C spec, the uint16 fields would
promote to int not unsigned int, so that (for 32-bit int) the shift
potentially shifts a nonzero bit into the sign position. I doubt
there are any production systems where this would actually end with
the wrong answer, but it is undefined behavior per the C spec, and
clang's -fsanitize=undefined option reputedly warns about it on some
platforms. (I can't reproduce that right now, but the code is
undeniably wrong per spec.) It's easy to fix by casting to
BlockNumber (uint32) in the proper places.

It's been wrong for ages, so back-patch to all supported branches.

Report and patch by Zhihong Yu (cosmetic tweaking by me)

Discussion: https://postgr.es/m/CALNJ-vT9r0DSsAOw9OXVJFxLENoVS_68kJ5x0p44atoYH+H4dg@mail.gmail.com

Branch
------
REL_10_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/18c04d1574568fd68e4f498483f3b10b11018c68

Modified Files
--------------
src/include/storage/block.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

Browse pgsql-committers by date

  From Date Subject
Next Message Tom Lane 2022-03-04 00:15:50 pgsql: Remove some pointless code in block.h.
Previous Message Tom Lane 2022-03-03 23:13:53 pgsql: Clean up assorted failures under clang's -fsanitize=undefined ch