delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2003/01/01/23:38:59

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Message-ID: <3E13C1E1.1000103@ece.gatech.edu>
Date: Wed, 01 Jan 2003 23:36:49 -0500
From: Charles Wilson <cwilson AT ece DOT gatech DOT edu>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.1) Gecko/20020823 Netscape/7.0
X-Accept-Language: en-us, en
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Re: Heads up: *possible* bug in cygwin
References: <E18PoeB-0000fC-00 AT quimby DOT gnus DOT org> <3E05BD05 DOT 5090408 AT ece DOT gatech DOT edu> <3E0DDE19 DOT 1060903 AT ece DOT gatech DOT edu> <3E10A7AE DOT 20405 AT ece DOT gatech DOT edu> <3E10C29B DOT 2010709 AT ece DOT gatech DOT edu> <3E111AAF DOT 3090008 AT ece DOT gatech DOT edu> <20021231043913 DOT GA26944 AT redhat DOT com> <3E11AD26 DOT 8050506 AT ece DOT gatech DOT edu> <20021231175349 DOT GC6542 AT redhat DOT com> <3E123A28 DOT 8030705 AT ece DOT gatech DOT edu> <1041383123 DOT 6526 DOT 13 DOT camel AT lifelesswks> <3E137A39 DOT 9050204 AT ece DOT gatech DOT edu>

Turns out, the problem IS in newlib.

> First, create a buffer of the appropriate length:
> buffer = g_new (gchar, g_printf_string_upper_bound (format, args1));
> 
> And then format the data into that buffer.
> vsprintf (buffer, format, args2);
> 
> But the buffer isn't long enough, so the actual problem is *probably* 
> somewhere in the g_printf_string_upper_bound() routine, that computes 
> the appropriate length.

Well, not exactly.  g_printf_string_upper_bound returns 30k, which is 
more than sufficient, actually.  An annotated "stack trace" is below.

(ignore the stuff about impure_ptr, I wrote that stuff when I thought 
there was a problem with insuffient memory allocation in that structure, 
as used by *printf.  I was both right and wrong, but impure_ptr is not 
the problem...)

vsprintf
   initializes a FILE variable f.  Sets f._data = _impure_ptr
   calls vfprintf(&f, ....)

vfprintf
   makes sure f is good (which it will be, in this case)
   calls _vfprintf_r(f->_data, ...)  which is simply
   _vfprintf_r(impure_ptr, ...)

_vfprintf_r
   does the basic work.  When the fmt string has a %f or other floating 
point specifier, it calls cvt(data, ...) to do the actual formatting. 
data is simply impure_ptr.

cvt
   sets 'char *digits' to _ldtoa_r(data, ....) [again, data is our 
impure_ptr.)

_ldtoa_r
   first off , enforces a limit on ndigits of 42 on cygwin (see ldtoa.c, 
#define NDEC for the algorithm).  So 10000 is right out.  However, this 
is the problem:

cvt doesn't know that _ldtoa_r overrode ndigits to a "mere" 42.  So, in 
this code (part of cvt()):

1168		digits = _ldtoa_r(data, value, mode, ndigits, decpt, &dsgn, &rve);	
1169	#endif /* !_NO_LONGDBL */
1170	
1171		if ((ch != 'g' && ch != 'G') || flags & ALT)
1172			bp = digits + ndigits;

we set bp to something WAY past the end of digits.  Since rve points to 
the actual end of digits (where the '\0' is)...

1173			if (ch == 'f') {
1174				if (*digits == '0' && value)
1175					*decpt = -ndigits + 1;
1176				bp += *decpt;
1177			}
1178			if (value == 0)
1179				rve = bp;
1180			while (rve < bp)
1181				*rve++ = '0';

and then try to put 0's into digits[43...10000] in the while loop (lines 
1180 and 1181).  But, there were only 24 +  (2^3-1)*4 == 52 bytes 
allocated for digits.

I'm not sure what the correct fix is...should ndigits be passed by 
reference to _ldtoa_r, so that cvt "knows" that it got changed?  (Ditto 
pass-by-reference to cvt so that vfprintf_r knows about the override as 
well).  This changes the signature of these two (admittedly internal) 
routines, but I'm not sure of the "ripple effects" such a change might 
cause.

Or is this a case of "doctor, it hurts when I do this?" "Don't call 
printf with prec specifiers greater than 42, then."

--Chuck


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019