Subject: Re: lib/35401
To: None <lib-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Thorsten Glaser <tg@mirbsd.de>
List: netbsd-bugs
Date: 01/11/2007 20:45:02
The following reply was made to PR lib/35401; it has been noted by GNATS.

From: Thorsten Glaser <tg@mirbsd.de>
To: gnats-bugs@NetBSD.org
Cc: Felix von Leitner <leitner@codeblau.de>,
	Benny Siegert <bsiegert@MirBSD.org>
Subject: Re: lib/35401
Date: Thu, 11 Jan 2007 20:39:18 +0000 (UTC)

 (Adding Felix himself to the discussion, maybe he's got
 some more ideas.)
 
 Andreas Wiese dixit:
 
 >Inspired by http://blog.fefe.de/?ts=3Dbb5b972c
 
 Please note the patch committed to MirOS BSD yesterday, which
 I have attached below (inline). It won't apply cleanly to
 NetBSD=C2=AE-current as is, but you get the idea.
 
 >Since errno is not set, I think this isn't recognized as an error (even
 >with negative return value).  Could be naughty, couldn't it?
 
 According to (my) TFM, only -1 is an error.
 
 >But hey, at least it doesn't waste 1GB of RAM and 17secs like the GNU
 >implementation ;)
 
 ;)
 
 Christian Biere dixit:
 
 >For what it's worth, this has undefined behaviour even though it probably =
 just
 >works with the current GCC.
 
 Hm, "in theory" true, but "our" integers are 32 bits, and
 the new value is either larger or equal, or it isn't.
 
 The point of my patch is not to check if it's below zero,
 but - and that is the actual thing mentioned by fefe - if
 it is smaller. If you continue to play the game, you will
 find ways to make asprintf() allocate less memory than is
 needed.
 
 Setting errno to ERANGE sounds feasible, though.
 
 //mirabile
 --=20
   "Using Lynx is like wearing a really good pair of shades: cuts out
    the glare and harmful UV (ultra-vanity), and you feel so-o-o COOL."
                                          -- Henry Nelson, March 1999
 
 
 Index: vfprintf.c
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: /cvs/src/lib/libc/stdio/vfprintf.c,v
 retrieving revision 1.3
 retrieving revision 1.4
 diff -u -p -r1.3 -r1.4
 --- vfprintf.c=0922 Sep 2005 20:13:05 -0000=091.3
 +++ vfprintf.c=0910 Jan 2007 23:28:12 -0000=091.4
 @@ -209,8 +209,16 @@ vfprintf(FILE *fp, const char *fmt0, _BS
  =09 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
 =20
  =09/*
  =09 * BEWARE, these `goto error' on error, and PAD uses `n'.
  =09 */
 +#define=09ADDTORET(x) do {=09\
 +=09int oldret =3D ret;=09\
 +=09ret +=3D (x);=09=09\
 +=09if (oldret > ret) {=09\
 +=09=09ret =3D EOF;=09\
 +=09=09goto error;=09\
 +=09}=09=09=09\
 +} while (0)
  #define=09PRINT(ptr, len) do { \
  =09iovp->iov_base =3D (ptr); \
  =09iovp->iov_len =3D (len); \
 @@ -327,7 +335,7 @@ vfprintf(FILE *fp, const char *fmt0, _BS
  =09=09}
  =09=09if ((m =3D fmt - cp) !=3D 0) {
  =09=09=09PRINT(cp, m);
 -=09=09=09ret +=3D m;
 +=09=09=09ADDTORET(m);
  =09=09}
  =09=09if (n <=3D 0)
  =09=09=09goto done;
 @@ -763,7 +771,7 @@ number:=09=09=09if ((dprec =3D prec) >=3D 0)
  =09=09=09PAD(width - realsz, blanks);
 =20
  =09=09/* finally, adjust ret */
 -=09=09ret +=3D width > realsz ? width : realsz;
 +=09=09ADDTORET(width > realsz ? width : realsz);
 =20
  =09=09FLUSH();=09/* copy out the I/O vectors */
  =09}