Bug#969618: getopt: optarg is NULL outside of loop

2020-09-06 Thread Aurelien Jarno
Hi,

On 2020-09-06 09:25, Florian Weimer wrote:
> * John Scott:
> 
> > #define _POSIX_C_SOURCE 200809L
> > #include 
> > #include 
> > #include 
> > #include 
> > int main(int argc, char *argv[]) {
> > int opt;
> > while((opt = getopt(argc, argv, "a:")) != -1) {}
> > assert(optarg != NULL);
> > }
> >
> > If this is invoked as './a.out -afoo', the inner assertion will
> > the last assertion will fail with glibc.
> 
> POSIX leaves it unspecified if optarg is changed if getopt returns -1.
> Only optind must be left unchanged.  I do not think this is a glibc
> bug (or a musl bug).

Thanks Florian for the explanations. This can be confirmed that optarg
is not NULL by moving the assert in the while loop. So it doesn't seems
like a bug to me.

Aurelien

-- 
Aurelien Jarno  GPG: 4096R/1DDD8C9B
aurel...@aurel32.net http://www.aurel32.net



Bug#969618: getopt: optarg is NULL outside of loop

2020-09-06 Thread Florian Weimer
* John Scott:

> #define _POSIX_C_SOURCE 200809L
> #include 
> #include 
> #include 
> #include 
> int main(int argc, char *argv[]) {
>   int opt;
>   while((opt = getopt(argc, argv, "a:")) != -1) {}
>   assert(optarg != NULL);
> }
>
> If this is invoked as './a.out -afoo', the inner assertion will
> the last assertion will fail with glibc.

POSIX leaves it unspecified if optarg is changed if getopt returns -1.
Only optind must be left unchanged.  I do not think this is a glibc
bug (or a musl bug).



Bug#969618: getopt: optarg is NULL outside of loop

2020-09-05 Thread John Scott
Package: libc6
Version: 2.31-3
Severity: normal
X-Debbugs-Cc: 

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

I suspect this is an upstream problem but I'm reporting it here
first per their policy [1] since I'm unsure.

Both POSIX (including the Issue 8 draft) and the GNU C Library
manual say that when an argument is provided for an option, a
pointer to it is provided as optarg.

It seems like after leaving the while() loop getopt is usually
used in, optarg points to NULL instead, even if no other options,
bearing arguments or not, are used. It's a little grey but POSIX
doesn't seem to permit this, and the (non-DFSG) glibc manual could
be construed as saying it should work fine this way:
> If the option has an argument, getopt returns the argument by storing
> it in the variable optarg. You don’t ordinarily need to copy the optarg
> string, since it is a pointer into the original argv array, not into a
> static area that might be overwritten. 

Everything works fine with Musl libc which can be tried with musl-gcc.
Consider this example program:

#define _POSIX_C_SOURCE 200809L
#include 
#include 
#include 
#include 
int main(int argc, char *argv[]) {
int opt;
while((opt = getopt(argc, argv, "a:")) != -1) {}
assert(optarg != NULL);
}

If this is invoked as './a.out -afoo', the inner assertion will
the last assertion will fail with glibc. In the absence of
a compelling reason (such as if I were using the GNU extension of
having an optional argument via '::'), standards aside, it would
be helpful for me if the variable could be left alone.

[1] https://sourceware.org/glibc/wiki/FilingBugs
[2] https://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html
- -- System Information:
Debian Release: bullseye/sid
  APT prefers testing
  APT policy: (500, 'testing'), (2, 'unstable'), (1, 'testing-debug'), (1, 
'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 5.7.0-3-amd64 (SMP w/2 CPU threads)
Kernel taint flags: TAINT_USER, TAINT_FIRMWARE_WORKAROUND
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages libc6 depends on:
ii  libcrypt1  1:4.4.17-1
ii  libgcc-s1  10.2.0-5

Versions of packages libc6 recommends:
ii  libidn2-0  2.3.0-1

Versions of packages libc6 suggests:
ii  debconf [debconf-2.0]  1.5.74
ii  glibc-doc  2.31-3
ii  libc-l10n  2.31-3
ii  locales2.31-3

- -- debconf information:
  glibc/restart-failed:
  glibc/upgrade: true
  glibc/kernel-too-old:
  glibc/kernel-not-supported:
* libraries/restart-without-asking: true
  glibc/disable-screensaver:
  glibc/restart-services:

-BEGIN PGP SIGNATURE-

iHUEARYIAB0WIQT287WtmxUhmhucNnhyvHFIwKstpwUCX1Q6TgAKCRByvHFIwKst
p+D0AQDqLFwxGh/oTV+13E5stB3WvG9zD0tpMiol/xHW0QuERgEAsPKsGbQBW2nG
VFzkfExA5cGyGj0GW7IyKg42+wLaZgI=
=WQf5
-END PGP SIGNATURE-