Bug#609756: vsnprintf segfaults on second attempt with alloca
Package: libc6
Version: 2.7-18lenny7
C99 only va_copy does help. This is a new one for me.
Does vfnprint destroy the callers ap?
Does this break C89 and C90?
Gcc did not require -std=c99 or -std=gnu99 to accept va_copy.
Assuming <stdarg.h> was something like
#define va_start(ap, last) (ap)=(va_list)(&(last)+sizeof(last))
#define va_arg(ap, type) ((ap)+=sizeof(type),(type)*((ap)-sizeof(type)))
would be wrong.
On Wed, 12 Jan 2011 10:18:41 +0000
Florian Weimer <fweimer@bfk.de> wrote:
> * Andrew Buckeridge:
>
> > int vfprint(int fdout, const char *fmt, va_list ap)
> > {
> > int i=NONSTDBUF;
> > i=vfnprint(fdout, i, fmt, ap);
> > if(i<-1)
> > i=vfnprint(fdout, 1-i, fmt, ap);
> > return i;
> > }
>
> va_copy seems to be missing here.
>
> --
> Florian Weimer <fweimer@bfk.de>
> BFK edv-consulting GmbH http://www.bfk.de/
> Kriegsstraße 100 tel: +49-721-96201-1
> D-76133 Karlsruhe fax: +49-721-96201-99
/*
fprint.c - unistdio fprint function - Andrew Buckeridge
*/
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <alloca.h>
#include "fprint.h"
/*
#include <string.h>
*/
/* +Ve == bytes written -Ve == bytes required */
int vfnprint(int fdout, int r, const char *fmt, va_list ap)
{
int i;
char *p;
p=alloca(r);
p[r-1]='\0';
/*
memset(p,0,r);
*/
/* NB: alloca may return shit, but no it _IS_ vsnprintf */
fprintf(stderr,"\nvsnprintf(%d,%d,%p,...)=",fdout,r,fmt);
/* segfault inside this */
i=vsnprintf(p,r,fmt,ap);
fprintf(stderr,"=%d\n",i);
if(i<0) {
return 1-2*r;
}
if(i<r) {
return ((write(fdout,p,i))==i)?i:-1;
}
return -i;
}
/* +Ve == bytes written -Ve == failure */
int vfprint(int fdout, const char *fmt, va_list ap)
{
int i=NONSTDBUF;
va_list aq;
va_copy(aq,ap);
i=vfnprint(fdout, i, fmt, ap);
if(i<-1)
i=vfnprint(fdout, 1-i, fmt, aq);
va_end(aq);
return i;
}
int fprint(int fdout, const char *fmt, ...)
{
va_list ap;
int r;
va_start(ap, fmt);
r=vfprint(fdout, fmt, ap);
va_end(ap);
return r;
}
Reply to: