public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
From: Corinna Vinschen <vinschen@redhat.com>
To: newlib@sourceware.org
Cc: Jon Turney <jon.turney@dronecode.org.uk>
Subject: Re: bug with printf positional arguments?
Date: Wed, 26 Jul 2023 15:26:58 +0200	[thread overview]
Message-ID: <ZMEfInC5pnRaPmS/@calimero.vinschen.de> (raw)
In-Reply-To: <e2ae3f9f-0d60-32e7-af9a-aa689128e19a@dronecode.org.uk>

On Jul  3 15:49, Jon Turney wrote:
> On 03/07/2023 12:14, Corinna Vinschen wrote:
> > On Jun 28 14:28, Jon Turney wrote:
> > > 
> > > The following trivial program (extracted from a glib testcase)
> > > 
> > > > #include <stdio.h>
> > > > 
> > > > int main()
> > > > {
> > > >    printf ("%1$*2$.*3$s", "abc", 5, 2);
> > > > }
> > > 
> > > does not produce the expected output of "   ab", on 64-bit Cygwin.
> > > 
> > >  From a bit of staring at and stepping through get_args() in
> > > libc/stdio/vfprintf.c, it looks like the problem is (something like) we
> > > don't have the knowledge that the first positional variadic argument should
> > > be treated as a pointer, at the point that we store it's value, so it gets
> > > treated as an integer (the default), which is going to lead to truncation on
> > > LP64 platforms.
> > > 
> > > A straightforward way to fix this eludes me.
> > 
> > Can you point out where in the code this problem occurs, so maybe
> > we can discuss the necessary code changes in this thread?
> 
> Sure, I'll try:
> 
> Let's suppose you're executing the STC above. This is what I think
> happens...
> 
> We end up in _vprintf_r.
> 
> We hit line 1072, which digests the '1', and on the following '$', knows to
> interpret this as a positional argument and stores it.
> 
> The subsequent '*' is processed at line 967 as introducing the width, where
> we chomp the '2', which again the following '$' indicates should be treated
> as a positional arg.
> 
> We hit GET_ARG for the first time, to retrieve the width, which invokes
> get_arg() to do the work (as we haven't yet stored the requested arg in
> args[]).
> 
> get_arg() digests the format string (again) using a state machine (to
> populate args[] with the positional parameters)
> 
> The state machine moves through START (action NUMBER) -> WDIG (action
> GETPOS) -> DONE.
> 
> Stopping here looks like maybe an error in the state machine design?
> 
> The loop starting at line 2310 iterates over the seen args, fetching their
> values. Because we haven't processed the 's' at the end in the GETARG state,
> we retrieve the first argument using the default case, as an integer (32
> bits, truncating the 64-bit pointer value) (it looks like we're maybe also
> lucking out on handling the width properly, as we're never hitting the PWPOS
> state to record that it should be treated as an INT).

After going a bit cross-eyed looking at the code, I *seriously* wonder,
if we shouldn't start with fresh vfprintf_r/vfwprintf_r, using copies of
the most recent FreeBSD vfprintf/vfwprintf, and just carefully tweak them
to match our build system...


Corinna


      reply	other threads:[~2023-07-26 13:27 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-28 13:28 Jon Turney
2023-07-03 11:14 ` Corinna Vinschen
2023-07-03 14:49   ` Jon Turney
2023-07-26 13:26     ` Corinna Vinschen [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZMEfInC5pnRaPmS/@calimero.vinschen.de \
    --to=vinschen@redhat.com \
    --cc=jon.turney@dronecode.org.uk \
    --cc=newlib@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).