[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#969618: marked as done (getopt: optarg is NULL outside of loop)



Your message dated Sun, 11 Oct 2020 13:11:57 +0200
with message-id <20201011111157.GA1454307@aurel32.net>
and subject line Re: Bug#969618: getopt: optarg is NULL outside of loop
has caused the Debian Bug report #969618,
regarding getopt: optarg is NULL outside of loop
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
969618: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=969618
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
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 <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
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  locales                2.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-----

--- End Message ---
--- Begin Message ---
On 2020-09-06 21:47, Aurelien Jarno wrote:
> Hi,
> 
> On 2020-09-06 09:25, Florian Weimer wrote:
> > * John Scott:
> > 
> > > #define _POSIX_C_SOURCE 200809L
> > > #include <assert.h>
> > > #include <stdio.h>
> > > #include <stdlib.h>
> > > #include <unistd.h>
> > > 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.

I am therefore closing it.

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

--- End Message ---

Reply to: