postgres.git / summary / log / commit / refs

commit    a2acafc7be7a957e72234bb28b83a5e4d2bc019f
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Sun Oct 16 15:47:44 2022 +0000
First released in: 16.0, 12.13, 13.9, 14.6, 15.1

    Use libc's snprintf, not sprintf, for special cases in snprintf.c.
    
    snprintf.c has always fallen back on libc's *printf implementation
    when printing pointers (%p) and floats.  When this code originated,
    we were still supporting some platforms that lacked native snprintf,
    so we used sprintf for that.  That's not actually unsafe in our usage,
    but nonetheless builds on macOS are starting to complain about sprintf
    being unconditionally deprecated; and I wouldn't be surprised if other
    platforms follow suit.  There seems little reason to believe that any
    platform supporting C99 wouldn't have standards-compliant snprintf,
    so let's just use that instead to suppress such warnings.
    
    Back-patch to v12, which is where we started to require C99.  It's
    also where we started to use our snprintf.c everywhere, so this
    wouldn't be enough to suppress the warning in older branches anyway
    --- that is, in older branches these aren't necessarily all our
    usages of libc's sprintf.  It is enough in v12+ because any
    deprecation annotation attached to libc's sprintf won't apply to
    pg_sprintf.  (Whether all our usages of pg_sprintf are adequately
    safe is not a matter I intend to address here, but perhaps it could
    do with some review.)
    
    Per report from Andres Freund and local testing.
    
    Discussion: https://postgr.es/m/20221015211955.q4cwbsfkyk3c4ty3@awork3.anarazel.de


src/port/snprintf.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/port/snprintf.c b/src/port/snprintf.c index 98e09c8b763..9c6eb493ee4 100644 --- a/src/port/snprintf.c +++ b/src/port/snprintf.c @@ -1002,8 +1002,8 @@ fmtptr(const void *value, PrintfTarget *target) int vallen; char convert[64]; - /* we rely on regular C library's sprintf to do the basic conversion */ - vallen = sprintf(convert, "%p", value); + /* we rely on regular C library's snprintf to do the basic conversion */ + vallen = snprintf(convert, sizeof(convert), "%p", value); if (vallen < 0) target->failed = true; else @@ -1129,11 +1129,11 @@ fmtfloat(double value, char type, int forcesign, int leftjust, int padlen; /* amount to pad with spaces */ /* - * We rely on the regular C library's sprintf to do the basic conversion, + * We rely on the regular C library's snprintf to do the basic conversion, * then handle padding considerations here. * * The dynamic range of "double" is about 1E+-308 for IEEE math, and not - * too wildly more than that with other hardware. In "f" format, sprintf + * too wildly more than that with other hardware. In "f" format, snprintf * could therefore generate at most 308 characters to the left of the * decimal point; while we need to allow the precision to get as high as * 308+17 to ensure that we don't truncate significant digits from very @@ -1185,14 +1185,14 @@ fmtfloat(double value, char type, int forcesign, int leftjust, fmt[2] = '*'; fmt[3] = type; fmt[4] = '\0'; - vallen = sprintf(convert, fmt, prec, value); + vallen = snprintf(convert, sizeof(convert), fmt, prec, value); } else { fmt[0] = '%'; fmt[1] = type; fmt[2] = '\0'; - vallen = sprintf(convert, fmt, value); + vallen = snprintf(convert, sizeof(convert), fmt, value); } if (vallen < 0) goto fail; @@ -1321,7 +1321,7 @@ pg_strfromd(char *str, size_t count, int precision, double value) fmt[2] = '*'; fmt[3] = 'g'; fmt[4] = '\0'; - vallen = sprintf(convert, fmt, precision, value); + vallen = snprintf(convert, sizeof(convert), fmt, precision, value); if (vallen < 0) { target.failed = true; [parent: ad8129237055]