Skip to content
Snippets Groups Projects
Commit 70d4a934 authored by Bruce Momjian's avatar Bruce Momjian
Browse files

Prevent large allocation in snprintf to hold positional parameters.

Allocated size based on format string.
parent 3104a928
No related branches found
No related tags found
No related merge requests found
...@@ -32,18 +32,17 @@ ...@@ -32,18 +32,17 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
/* might be in either frontend or backend */ #ifndef FRONTEND
#include "postgres.h"
#else
#include "postgres_fe.h" #include "postgres_fe.h"
#endif
#ifndef WIN32 #ifndef WIN32
#include <sys/ioctl.h> #include <sys/ioctl.h>
#endif #endif
#include <sys/param.h> #include <sys/param.h>
#ifndef NL_ARGMAX
#define NL_ARGMAX 4096
#endif
/* /*
** SNPRINTF, VSNPRINT -- counted versions of printf ** SNPRINTF, VSNPRINT -- counted versions of printf
** **
...@@ -66,7 +65,7 @@ ...@@ -66,7 +65,7 @@
* causing nasty effects. * causing nasty effects.
**************************************************************/ **************************************************************/
/*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.11 2005/03/02 03:21:52 momjian Exp $";*/ /*static char _id[] = "$PostgreSQL: pgsql/src/port/snprintf.c,v 1.12 2005/03/02 05:22:22 momjian Exp $";*/
int snprintf(char *str, size_t count, const char *fmt,...); int snprintf(char *str, size_t count, const char *fmt,...);
int vsnprintf(char *str, size_t count, const char *fmt, va_list args); int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
...@@ -157,11 +156,9 @@ dopr(char *buffer, const char *format, va_list args, char *end) ...@@ -157,11 +156,9 @@ dopr(char *buffer, const char *format, va_list args, char *end)
int realpos = 0; int realpos = 0;
int position; int position;
char *output; char *output;
/* In thread mode this structure is too large. */ int percents = 1;
#ifndef ENABLE_THREAD_SAFETY const char *p;
static struct fmtpar {
#endif
struct{
const char* fmtbegin; const char* fmtbegin;
const char* fmtend; const char* fmtend;
void* value; void* value;
...@@ -179,10 +176,30 @@ dopr(char *buffer, const char *format, va_list args, char *end) ...@@ -179,10 +176,30 @@ dopr(char *buffer, const char *format, va_list args, char *end)
int pointflag; int pointflag;
char func; char func;
int realpos; int realpos;
} fmtpar[NL_ARGMAX+1], *fmtparptr[NL_ARGMAX+1]; } *fmtpar, **fmtparptr;
/* Create enough structures to hold all arguments */
for (p = format; *p != '\0'; p++)
if (*p == '%') /* counts %% as two, so overcounts */
percents++;
#ifndef FRONTEND
fmtpar = pgport_palloc(sizeof(struct fmtpar) * percents);
fmtparptr = pgport_palloc(sizeof(struct fmtpar *) * percents);
#else
if ((fmtpar = malloc(sizeof(struct fmtpar) * percents)) == NULL)
{
fprintf(stderr, _("out of memory\n"));
exit(1);
}
if ((fmtparptr = malloc(sizeof(struct fmtpar *) * percents)) == NULL)
{
fprintf(stderr, _("out of memory\n"));
exit(1);
}
#endif
format_save = format; format_save = format;
output = buffer; output = buffer;
while ((ch = *format++)) while ((ch = *format++))
{ {
...@@ -418,9 +435,7 @@ dopr(char *buffer, const char *format, va_list args, char *end) ...@@ -418,9 +435,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
performpr: performpr:
/* shuffle pointers */ /* shuffle pointers */
for(i = 1; i < fmtpos; i++) for(i = 1; i < fmtpos; i++)
{
fmtparptr[i] = &fmtpar[fmtpar[i].realpos]; fmtparptr[i] = &fmtpar[fmtpar[i].realpos];
}
output = buffer; output = buffer;
format = format_save; format = format_save;
while ((ch = *format++)) while ((ch = *format++))
...@@ -465,6 +480,14 @@ nochar: ...@@ -465,6 +480,14 @@ nochar:
; /* semicolon required because a goto has to be attached to a statement */ ; /* semicolon required because a goto has to be attached to a statement */
} }
*output = '\0'; *output = '\0';
#ifndef FRONTEND
pgport_pfree(fmtpar);
pgport_pfree(fmtparptr);
#else
free(fmtpar);
free(fmtparptr);
#endif
} }
static void static void
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment