Re: [PATCH] Fix missing argument handling in psql getopt

From: Quentin Rameau <quinq(at)fifth(dot)space>
To: pgsql-hackers(at)postgresql(dot)org
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Subject: Re: [PATCH] Fix missing argument handling in psql getopt
Date: 2019-08-25 19:00:09
Message-ID: 20190825210009.586cfd5c@fifth.space
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

> > “If the option was the last character in the string pointed to by an
> > element of argv, then optarg shall contain the next element of argv,
> > and optind shall be incremented by 2. If the resulting value of optind
> > is greater than argc, this indicates a missing option-argument, and
> > getopt() shall return an error indication.”
>
> Hm, interesting --- glibc doesn't seem to do that (advance optind past
> argc), nor do any of the principal BSDen. I see that this could be
> read as requiring it, but it seems like musl is pretty out of step
> by reading it that way.

Yes they don't, but the specification looks pretty clear to me, there's
nothing ambiguous about it.
Now it's a matter of implementation willing to adhere or not to it.

> I actually don't care for that code very much and would prefer that
> we nuke it entirely, because I think it's assuming more than it ought to
> about the meaning of optind: in the case of multiple option letters in one
> argv element, it's unspecified exactly when optind advances.

Yes, optind shouldn't be used this way here.
But it's specified exactly how and when optind advances, following the
above code, which specifies the first use case of separated option and
argument, there's a second case for grouped option and argument:

“Otherwise, optarg shall point to the string following the option
character in that element of argv, and optind shall be incremented by 1.”

> So the other
> problem here is that sometimes it's looking at the argv element *before*
> the relevant one. (It's easily demonstrated that this is so with glibc's
> getopt().) Probably that doesn't ever result in wrong behavior in
> practice, but it still seems bogus.
>
> The normal case of "psql -?" is handled before we ever get to this code,
> so if we just deleted '?' entirely from this logic, it would mostly do
> what we want. The case that would change is, eg,
>
> psql -f foo -?
>
> where now you get a usage message but you'd just get an "invalid option"
> complaint without the special case. Seeing that none of our other
> command-line programs have this special case, I'm not sure why psql
> still does.

Another better way, I think, to fix this is to check for optopt
instead, which would be set to the option which caused the error, which
if empty means there isn't an error.

Patch attached.

Attachment Content-Type Size
0001-Fix-handling-of-option.patch text/x-patch 961 bytes

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2019-08-25 19:14:46 Re: Outputting Standard SQL
Previous Message Ibrar Ahmed 2019-08-25 18:50:44 Re: pg_upgrade: Error out on too many command-line arguments