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


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.
 
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.
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.
 
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.  That is, should the offending format--or the start
of it--be printed?  (Determining the end of a bad format could be hard
to
do.)  So a couple of alternative thoughts (starting at 2, as the first
idea above is #1):
1)  print through the offending character
2)  print an error message (I don't like this much, but it is one of the
natural possiblities that comes to mind)
3)  print the whole format from the offending part to the end without
any conversion at all.
Example, given printf("%d OK; %***s\n", 1, 6, "abc"), would produce:
1)  "1 OK"
2)  "1 OK %**"
3)  "1 OK %**[FORMAT ERROR]" [or some other error string--no newline]
4)  "1 OK; %***s\n" [\n being a newline, not being a format conversion]
 
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.  For portability purposes should the L
be ignored and the argument treated as double?  Or should it be treated
as a bad format?  This question is quite similar to the "%***s" case,
falling under the general category of invalid format specifications.
(Should this be it's own thread--I had planned to ask after Jeff was
back--or is it appropriate for it to be included in this one?)
 
Craig

-----Original Message-----
From: newlib-owner@sourceware.org [mailto:newlib-owner@sourceware.org]
On Behalf Of Corinna Vinschen
Sent: Tuesday, November 24, 2009 11:44 AM
To: newlib@sourceware.org
Subject: printf field width argument handling

Hi,


better don't try this on your machine:

  printf ("%*********s", 6, "abc");

It's an almost sure way to let the CPU run away.  Yes, it's a malformed
format string.  But still, instead of bailing out early, every single
'*' will result in reading the next argument from the argument list to
fetch the field width.  The same occurs for precision specifiers.

It does not occur in glibc, though.  So my question is this.  Shouldn't
we avoid to do that and stop converting further arguments into width and
precision values after the first '*' has been handled?  And if so, what
would be the most useful error reaction?


Corinna

-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat


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