mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-03 08:00:21 +08:00
Prevent large allocation in snprintf to hold positional parameters.
Allocated size based on format string.
This commit is contained in:
parent
3104a92866
commit
70d4a9343f
@ -32,18 +32,17 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* might be in either frontend or backend */
|
||||
#ifndef FRONTEND
|
||||
#include "postgres.h"
|
||||
#else
|
||||
#include "postgres_fe.h"
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifndef NL_ARGMAX
|
||||
#define NL_ARGMAX 4096
|
||||
#endif
|
||||
|
||||
/*
|
||||
** SNPRINTF, VSNPRINT -- counted versions of printf
|
||||
**
|
||||
@ -66,7 +65,7 @@
|
||||
* 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 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)
|
||||
int realpos = 0;
|
||||
int position;
|
||||
char *output;
|
||||
/* In thread mode this structure is too large. */
|
||||
#ifndef ENABLE_THREAD_SAFETY
|
||||
static
|
||||
#endif
|
||||
struct{
|
||||
int percents = 1;
|
||||
const char *p;
|
||||
struct fmtpar {
|
||||
const char* fmtbegin;
|
||||
const char* fmtend;
|
||||
void* value;
|
||||
@ -179,10 +176,30 @@ dopr(char *buffer, const char *format, va_list args, char *end)
|
||||
int pointflag;
|
||||
char func;
|
||||
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;
|
||||
|
||||
output = buffer;
|
||||
while ((ch = *format++))
|
||||
{
|
||||
@ -418,9 +435,7 @@ dopr(char *buffer, const char *format, va_list args, char *end)
|
||||
performpr:
|
||||
/* shuffle pointers */
|
||||
for(i = 1; i < fmtpos; i++)
|
||||
{
|
||||
fmtparptr[i] = &fmtpar[fmtpar[i].realpos];
|
||||
}
|
||||
output = buffer;
|
||||
format = format_save;
|
||||
while ((ch = *format++))
|
||||
@ -465,6 +480,14 @@ nochar:
|
||||
; /* semicolon required because a goto has to be attached to a statement */
|
||||
}
|
||||
*output = '\0';
|
||||
|
||||
#ifndef FRONTEND
|
||||
pgport_pfree(fmtpar);
|
||||
pgport_pfree(fmtparptr);
|
||||
#else
|
||||
free(fmtpar);
|
||||
free(fmtparptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user