Date: Wed, 03 Dec 2025 19:39:26 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 291374] getopt(3) GNU extension wrong behavior Message-ID: <bug-291374-227@https.bugs.freebsd.org/bugzilla/>
index | next in thread | raw e-mail
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=291374 Bug ID: 291374 Summary: getopt(3) GNU extension wrong behavior Product: Base System Version: 14.3-STABLE Hardware: Any OS: Any Status: New Severity: Affects Some People Priority: --- Component: bin Assignee: bugs@FreeBSD.org Reporter: eugen@freebsd.org Flags: mfc-stable15?, mfc-stable14?, mfc-stable13? >From the getopt(3) manual page: The option string optstring may contain the following elements: individual characters, and characters followed by a colon to indicate an option argument is to follow. If an individual character is followed by two colons, then the option argument is optional; optarg is set to the rest of the current argv word, or NULL if there were no more characters in the current word. This is a GNU extension. For example, an option string "x" recognizes an option "-x", and an option string "x:" recognizes an option and argument "-x argument". It does not matter to getopt() if a following argument has leading white space. Note the last clause about leading white space. It does not match the code. For example, our date(1) utility uses getopt(argc, argv, "f:I::jnRr:uv:z:") and look at this: $ date -Idate 2025-12-04 $ date -I date date: illegal time format usage: date [-jnRu] [-I[date|hours|minutes|seconds]] [-f input_fmt] [-r filename|seconds] [-v[+|-]val[y|m|w|d|H|M|S]] [[[[[[cc]yy]mm]dd]HH]MM[.SS] | new_date] [+output_fmt] But this is not all. Consider the following simple test programm: #include <stdio.h> #include <unistd.h> int main(int argc, char *argv[]) { int ch; while ((ch = getopt(argc, argv, "cCd::F:lnoOp:s:u:U:wW")) != -1) { printf("ch is %c optarg is %s\n", (char)ch, optarg ? optarg : " NULL"); } return (0); } Option list taken from our tftpd(8) programm that uses "-s path" for a chroot and optional "-d value" for debugging. Build it: cc -o getoptest -ansi -pedantic -Wall getoptest.c Run it: $ ./getoptest -l -w -d14 -s /usr/local/admin/tftproot -u admin -U 0 ch is l optarg is NULL ch is w optarg is NULL ch is d optarg is 14 ch is s optarg is /usr/local/admin/tftproot ch is u optarg is admin ch is U optarg is 0 So far, so good. And now: $ ./getoptest -l -w -d 14 -s /usr/local/admin/tftproot -u admin -U 0 ch is l optarg is NULL ch is w optarg is NULL ch is d optarg is NULL Option list silently truncated. No -s, no chrooting for tftpd. -- You are receiving this mail because: You are the assignee for the bug.home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-291374-227>
