This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: printf field width argument handling


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Howland Craig D (Craig) on 11/24/2009 12:31 PM:
> The answer to the first question--to avoid it or not--perhaps depends
> upon how expensive the answer is.  I think that there is an inexpensive
> answer that could be applied.
>  
> A suggestion for the error reaction is to stop conversion, return
> an error, and set errno to EINVAL.  EINVAL seems the most appropriate,
> as the format argument is invalid in the example case.

What does glibc print/return for the given example?

> A secondary question is what do do with good output before a bad format
> specification.  For example, printf("OK%***s", 6, "abc").  Since the
> return is either supposed to be the number of characters output or
> an error, an ideal answer might be that nothing at all were actually
> output.  So the example would not even print the "OK" before returning.

POSIX is silent on whether any bytes have been previously output on an
error return.  Detecting invalid strings prior to any output is indeed
better QoI, but it either requires two passes through the format string or
mallocing an arbitrary amount of storage to track what has been parsed so
far.  EINVAL is the recommended errno for this case of input.  So it is
compliant to do partial output and still return a negative value.

> But, if an I/O error occurs, characters are actually output before the
> error return.  And, glancing at the code, not putting anything good out
> before a bad spec looks to be relatively expensive, so I'd propose that
> all good up to the offending format bits would be output, so the example
> would output "OK" and then return a negative value && errno=EINVAL.

Sounds good to me.

>  
> However, since most code does not check return values from printf,
> another question is if there should be a visual aid for the developer
> to "see" a problem.

For printf, you could also set the ferror() flag on stdout.  That won't
help for s[n]printf, but a user that doesn't check the return value gets
what they deserve.  Beyond that, EINVAL bugs are avoidable if you forbid
the use of user-supplied format strings.

>  That is, should the offending format--or the start
> of it--be printed?

No.  I don't see how we can justify any debugging output for diagnosing
bad format strings.

>  
> In a related question that I had just started thinking about (because
> I just started working on strtold()), is what to do if certain flags
> do not apply on a given system.  My specific case in point is wondering
> what to do with "%Lg" if a system has an old compiler that does not
> actually support long double.

C89 requires long double.  If your compiler is older than that, you have
more serious problems.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAksMuKoACgkQ84KuGfSFAYDrYgCfaI/s1SZKRiD3DPEGQBo5YTCj
7egAoL1FcswXK8QCj5995GTnsqLxMPdR
=ydGR
-----END PGP SIGNATURE-----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]