NetBSD Problem Report #59443

From www@netbsd.org  Sun May 25 18:28:24 2025
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
	 client-signature RSA-PSS (2048 bits) client-digest SHA256)
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id EE1971A923C
	for <gnats-bugs@gnats.NetBSD.org>; Sun, 25 May 2025 18:28:23 +0000 (UTC)
Message-Id: <20250525182822.5C3F91A923D@mollari.NetBSD.org>
Date: Sun, 25 May 2025 18:28:22 +0000 (UTC)
From: contact+netbsd.org@hacktivis.me
Reply-To: contact+netbsd.org@hacktivis.me
To: gnats-bugs@NetBSD.org
Subject: getopt/getopt_long prints errors when +/- is present before :
X-Send-Pr-Version: www-1.0

>Number:         59443
>Category:       lib
>Synopsis:       getopt/getopt_long prints errors when +/- is present before :
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun May 25 18:30:00 +0000 2025
>Last-Modified:  Tue May 27 05:25:00 +0000 2025
>Originator:     Haelwenn (lanodan) Monnier
>Release:        10.0
>Organization:
>Environment:
NetBSD build 10.0 NetBSD 10.0 (GENERIC) #0: Thu Mar 28 08:33:33 UTC 2024  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC amd64

>Description:
When optstring contains a leading + or -, getopt(3)/getopt_long(3) ignores the immediately following : and prints errors.
>How-To-Repeat:
$ cat getopt_test.c
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

int
main(int argc, char *argv[])
{
        char *optstr = getenv("OPTSTR");

        int c = -1;
        while((c = getopt(argc, argv, optstr)) != -1)
        {
                /* blank */
        }

        return 0;
}
$ clang -std=c99 -g -O2 -Wall -Wextra -o getopt_test getopt_test.c
$ OPTSTR=":" ./getopt_test -f
$ OPTSTR="+:" ./getopt_test -f
getopt_test: unknown option -- f
$ OPTSTR="-:" ./getopt_test -f
getopt_test: unknown option -- f

$ cat getopt_long_test.c
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

int
main(int argc, char *argv[])
{
        char *optstr = getenv("OPTSTR");

        static struct option opts[] = {
                {0, 0, 0, 0},
        };

        int c = -1;
        while((c = getopt_long(argc, argv, optstr, opts, NULL)) != -1)
        {
                /* blank */
        }

        return 0;
}
$ clang -std=c99 -g -O2 -Wall -Wextra -o getopt_long_test getopt_long_test.c
$ OPTSTR=":" ./getopt_long_test -f
$ OPTSTR="+:" ./getopt_long_test -f
getopt_long_test: unknown option -- f
$ OPTSTR="-:" ./getopt_long_test -f 
getopt_long_test: unknown option -- f
$ OPTSTR=":" ./getopt_long_test --foobar 
$ OPTSTR="+:" ./getopt_long_test --foobar
getopt_long_test: unknown option -- foobar
$ OPTSTR="-:" ./getopt_long_test --foobar 
getopt_long_test: unknown option -- foobar
>Fix:

>Audit-Trail:
From: Thomas Klausner <wiz@gatalith.at>
To: NetBSD bugtracking <gnats-bugs@NetBSD.org>
Cc: 
Subject: Re: lib/59443: getopt/getopt_long prints errors when +/- is present
 before :
Date: Mon, 26 May 2025 08:39:54 +0200

 On Sun, May 25, 2025 at 06:30:00PM +0000, contact+netbsd.org@hacktivis.me wrote:
 > >Synopsis:       getopt/getopt_long prints errors when +/- is present before :

 Perhaps it's too early in the morning, but can you please also
 describe what behaviour you expected instead, and why?

 Thanks,
  Thomas

From: "Haelwenn (lanodan) Monnier" <contact+netbsd.org@hacktivis.me>
To: gnats-bugs@netbsd.org
Cc: lib-bug-people@netbsd.org, gnats-admin@netbsd.org,
	netbsd-bugs@netbsd.org
Subject: Re: lib/59443: getopt/getopt_long prints errors when +/- is present
 before :
Date: Tue, 27 May 2025 04:55:25 +0200

 [2025-05-26 06:40:01+0000] Thomas Klausner via gnats:
 >The following reply was made to PR lib/59443; it has been noted by GNATS.
 >
 >From: Thomas Klausner <wiz@gatalith.at>
 >To: NetBSD bugtracking <gnats-bugs@NetBSD.org>
 >Cc:
 >Subject: Re: lib/59443: getopt/getopt_long prints errors when +/- is present
 > before :
 >Date: Mon, 26 May 2025 08:39:54 +0200
 >
 > On Sun, May 25, 2025 at 06:30:00PM +0000, contact+netbsd.org@hacktivis.me wrote:
 > > >Synopsis:       getopt/getopt_long prints errors when +/- is present before :
 >
 > Perhaps it's too early in the morning, but can you please also
 > describe what behaviour you expected instead, and why?
 >
 > Thanks,
 >  Thomas

 Yeah, no problem, I expected the following to happen instead:

      $ OPTSTR=":" ./getopt_test -f
      $ OPTSTR="+:" ./getopt_test -f
      $ OPTSTR="-:" ./getopt_test -f

      $ OPTSTR=":" ./getopt_long_test -f
      $ OPTSTR="+:" ./getopt_long_test -f
      $ OPTSTR="-:" ./getopt_long_test -f
      $ OPTSTR=":" ./getopt_long_test --foobar
      $ OPTSTR="+:" ./getopt_long_test --foobar
      $ OPTSTR="-:" ./getopt_long_test --foobar

 And as far as I can tell, this code seems like it should match the expected behavior: https://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdlib/getopt_long.c?rev=1.28

 Best regards

From: Martin Husemann <martin@duskware.de>
To: "Haelwenn (lanodan) Monnier" <contact+netbsd.org@hacktivis.me>
Cc: gnats-bugs@netbsd.org
Subject: Re: lib/59443: getopt/getopt_long prints errors when +/- is present
 before :
Date: Tue, 27 May 2025 07:05:08 +0200

 On Tue, May 27, 2025 at 04:55:25AM +0200, Haelwenn (lanodan) Monnier wrote:
 > And as far as I can tell, this code seems like it should match the
 > expected behavior:
 > https://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdlib/getopt_long.c?rev=1.28

 Maybe unrelated, but I think there is a bug in the man page:

      o    return value in case of missing argument if first character (after +
           or -) in option string is not ':':

           GNU     returns '?'

           NetBSD  returns ':' (since NetBSD's getopt does).

 The 

 	is not ':'

 is inverted, isn't it? NetBSD returns : if the first char is ':'
 (otherwise '?'), at least that is what I think getopt(3) says.


 Martin

From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: lib/59443: getopt/getopt_long prints errors when +/- is present before :
Date: Tue, 27 May 2025 05:20:40 -0000 (UTC)

 contact+netbsd.org@hacktivis.me ("Haelwenn (lanodan) Monnier") writes:

 $ OPTSTR=":" ./getopt_long_test -f
 $ OPTSTR="+:" ./getopt_long_test -f
 getopt_long_test: unknown option -- f
 $ OPTSTR="-:" ./getopt_long_test -f
 getopt_long_test: unknown option -- f

 The PRINT_ERROR logic looks wrong.

 A leading ':' should suppress the message, but:

 #define PRINT_ERROR     ((opterr) && ((*options != ':') \
                                       || (IGNORE_FIRST && options[1] != ':')))


 Maybe:

 #define PRINT_ERROR     ((opterr) && !((*options == ':') \
                                       || (IGNORE_FIRST && options[1] == ':')))

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2025 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.