Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 625b38e

Browse filesBrowse files
committed
Set snprintf.c's maximum number of NL arguments to be 31.
Previously, we used the platform's NL_ARGMAX if any, otherwise 16. The trouble with this is that the platform value is hugely variable, ranging from the POSIX-minimum 9 to as much as 64K on recent FreeBSD. Values of more than a dozen or two have no practical use and slow down the initialization of the argtypes array. Worse, they cause snprintf.c to consume far more stack space than was the design intention, possibly resulting in stack-overflow crashes. Standardize on 31, which is comfortably more than we need (it looks like no existing translatable message has more than about 10 parameters). I chose that, not 32, to make the array sizes powers of 2, for some possible small gain in speed of the memset. The lack of reported crashes suggests that the set of platforms we use snprintf.c on (in released branches) may have no overlap with the set where NL_ARGMAX has unreasonably large values. But that's not entirely clear, so back-patch to all supported branches. Per report from Mateusz Guzik (via Thomas Munro). Discussion: https://postgr.es/m/CAEepm=3VF=PUp2f8gU8fgZB22yPE_KBS0+e1AHAtQ=09schTHg@mail.gmail.com
1 parent 3d0f68d commit 625b38e
Copy full SHA for 625b38e

File tree

Expand file treeCollapse file tree

1 file changed

+10
-6
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

1 file changed

+10
-6
lines changed
Open diff view settings
Collapse file

‎src/port/snprintf.c‎

Copy file name to clipboardExpand all lines: src/port/snprintf.c
+10-6Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,13 @@
4141
#endif
4242
#include <sys/param.h>
4343

44-
#ifndef NL_ARGMAX
45-
#define NL_ARGMAX 16
46-
#endif
44+
/*
45+
* We used to use the platform's NL_ARGMAX here, but that's a bad idea,
46+
* first because the point of this module is to remove platform dependencies
47+
* not perpetuate them, and second because some platforms use ridiculously
48+
* large values, leading to excessive stack consumption in dopr().
49+
*/
50+
#define PG_NL_ARGMAX 31
4751

4852

4953
/*
@@ -358,8 +362,8 @@ dopr(PrintfTarget *target, const char *format, va_list args)
358362
double fvalue;
359363
char *strvalue;
360364
int i;
361-
PrintfArgType argtypes[NL_ARGMAX + 1];
362-
PrintfArgValue argvalues[NL_ARGMAX + 1];
365+
PrintfArgType argtypes[PG_NL_ARGMAX + 1];
366+
PrintfArgValue argvalues[PG_NL_ARGMAX + 1];
363367

364368
/*
365369
* Parse the format string to determine whether there are %n$ format
@@ -409,7 +413,7 @@ dopr(PrintfTarget *target, const char *format, va_list args)
409413
goto nextch1;
410414
case '$':
411415
have_dollar = true;
412-
if (accum <= 0 || accum > NL_ARGMAX)
416+
if (accum <= 0 || accum > PG_NL_ARGMAX)
413417
goto bad_format;
414418
if (afterstar)
415419
{

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.