summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Freund2018-10-03 20:02:25 +0000
committerAndres Freund2018-10-03 20:13:50 +0000
commit4868e4468590bc32f9c3afed4ec795d6a7732c9d (patch)
treed95b4780cb47b4efe4aea8797ec016ff5791cfd8
parent9a3cebeaa7fdc1b0485475eb18121eb06968dc5d (diff)
Ensure that snprintf.c's fmtint() doesn't overflow when printing INT64_MIN.
This isn't actually a live bug, as the output happens to be the same. But it upsets tools like UBSan, which makes it worthwhile to fix. As it's an issue without practical consequences, don't backpatch. Author: Andres Freund Discussion: https://postgr.es/m/[email protected]
-rw-r--r--src/port/snprintf.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/src/port/snprintf.c b/src/port/snprintf.c
index 3bd598d75c..872d800124 100644
--- a/src/port/snprintf.c
+++ b/src/port/snprintf.c
@@ -1007,6 +1007,7 @@ fmtint(long long value, char type, int forcesign, int leftjust,
PrintfTarget *target)
{
unsigned long long base;
+ unsigned long long uvalue;
int dosign;
const char *cvt = "0123456789abcdef";
int signvalue = 0;
@@ -1045,7 +1046,9 @@ fmtint(long long value, char type, int forcesign, int leftjust,
/* Handle +/- */
if (dosign && adjust_sign((value < 0), forcesign, &signvalue))
- value = -value;
+ uvalue = -(uint64) value;
+ else
+ uvalue = (uint64) value;
/*
* SUS: the result of converting 0 with an explicit precision of 0 is no
@@ -1056,8 +1059,6 @@ fmtint(long long value, char type, int forcesign, int leftjust,
else
{
/* make integer string */
- unsigned long long uvalue = (unsigned long long) value;
-
do
{
convert[sizeof(convert) - (++vallen)] = cvt[uvalue % base];