[Toybox] [PATCH] Make yesno printf-like.

Rich Felker dalias at libc.org
Wed Sep 2 18:25:01 PDT 2015


On Wed, Sep 02, 2015 at 07:58:18PM -0500, Rob Landley wrote:
> On 09/02/2015 10:09 AM, enh wrote:
> > On Tue, Sep 1, 2015 at 11:26 PM, Rob Landley <rob at landley.net> wrote:
> >> On 09/01/2015 08:35 PM, enh wrote:
> >>> Make yesno printf-like.
> >>
> >> This just makes me uncomfortable that it's nonobvious enough somebody's
> >> going to yesno(1, usersupplieddata);.
> > 
> > that seems unlikely, especially given that yesno doesn't supply the
> > "?". (and you really ought to get out of the habit of being so tricky
> > at the cost of readability all the time anyway!)
> > 
> > btw, though this distracts from my point and will probably only
> > encourage you to stick with the status quo... toybox already blindly
> > uses user-supplied strings as format strings. random example:
> > 
> > $ seq -f '%s' 1 3
> > seq: format ‘%s’ has unknown %s directive
> > 
> > $ ./toybox seq -f '%s' 1 3
> > Segmentation fault (core dumped)
> 
> That's a bug and I need to fix it.
> 
> Except... Grrr. No posix entry for this, and the LSB spec is crap as usual.
> 
> seq -f %d 1 3
> seq -f %s 1 3
> seq -f "" 1 3
> seq -f %f 1 3
> seq -f %e 1 3
> seq -f %g 1 3
> seq -f "boo %f yah" 1 3
> seq -f "boo %f %f yah" 1 3
> seq -f "% f" 1 3
> seq -f "%*f" 1 3
> seq -f "%-1.2f" 1 3
> seq -f "%-1.2.3f" 1 3
> seq -f "%1-f" 1 3
> seq -f "%1 f" 1 3
> seq -f "%+-f" 1 3
> seq -f "%+ - f" 1 3
> seq -f "%.2f" 1 3
> seq -f "%3.f" 1 3
> seq -f "%2..2f" 1 3
> seq -f "%'.2f" 1 3
> 
> Ok, it looks like the sanitization pass is using:
> 
> 1) search for one % (must exist in string)
> 2) skip all "+- "
> 3) skip all digits 0-9
> 4) skip at most one "."
> 5) skip all digits 0-9
> 6) ensure next char is [feg]
> 
> Now let's read man 3 printf and see what ELSE I forgot: accept %%
> literal, the target is aAeEfFgG, flags are ['#-+ ]...
> 
> seq -f "%LF" 1 3
> 
> Really? Sigh. I don't think I'm allowing that one because it's INSANE.

This should work:

([^%]|%%)*%[-#0 +']?[0-9]*.[0-9]*[aAeEfFgG]([^%]|%%)*

If you're already linking regcomp/regexec, using them to match it is
probably the smallest/simplest implementation. If not you can write a
state machine for it.

Rich

 1441243501.0


More information about the Toybox mailing list