mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03: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.
|
* 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 @@
|
|||||||
* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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:
|
|||||||
; /* 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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user