On Thu, 20 Aug 2026 at 22:55, Rob Landley via busybox
<[email protected]> wrote:
>
> On 8/6/26 21:30, G. Branden Robinson via busybox wrote:
> > [looping in busybox mailing list; Bruno found a sed portability problem]
> >
> > Background:
> > https://savannah.gnu.org/bugs/?68601
> >
> > Hi Bruno,
> >
> > At 2026-08-06T18:07:55+0200, Bruno Haible wrote:
> >> I wrote:
> >>> The reason is that the 'sed' program on this platform (from BusyBox)
> >>> ignores '-e' options when a '-f' option is present, regardless
> >>> whether the '-e' options come before or after the '-f' option.
>
> Which apparently nobody noticed for 20 years.

Or nobody cared about it for 20 years, which is apparently the same
thing but it isn't.

sed.c: POSIX compliance fix about '-f' with '-e' ordered options v3
https://github.com/robang74/busybox/commit/825b8f85af52adfe14bc07eb3aaff5fcc50a7070

sed.c: POSIX compliance fix about '-f' with '-e' ordered options v2
https://github.com/robang74/busybox/commit/d1f50a14db96968d4ecc1cb042dfb83bd2cd6a01

Are these two solving the problem?

Best regards,
-- 
Roberto A. Foglietta
+49.176.274.75.661
+39.349.33.30.697
From 825b8f85af52adfe14bc07eb3aaff5fcc50a7070 Mon Sep 17 00:00:00 2001
From: "Roberto A. Foglietta" <[email protected]>
Date: Mon, 17 Aug 2026 08:57:33 +0200
Subject: [PATCH 2/9] sed.c: POSIX compliance fix about '-f' with '-e' ordered
 options v3

goal:

Processing '-e' and '-f' options in command line order for
achieving the POSIX compliance as expected by the command line.

how:

The getopt32long stores them in separate lists, losing
their relative order. We determine which appeared first
by finding which argv[] element each optarg points into.

bug:

- https://savannah.gnu.org/bugs/?68601

fix:

   text    data     bss     dec     hex filename
   7352       0       0    7352    1cb8 editors/sed.o
   7441       0       0    7441    1d11 editors/sed.o v1
   7465       0       0    7465    1d29 editors/sed.o v2
   7508       0       0    7508    1d54 editors/sed.o v3
                           +156

v1 --> v2:
- from string comparison to a more compatct options check
v2 --> v3:
- what about -nre? or -nve? uncommon but lecit and broken, fixed

requires:

- sed.c: POSIX compliance fix about '-f' with '-e' ordered options v2

todo:

- test in testsuite
- footprint reduction

Signed-off-by: Roberto A. Foglietta <[email protected]>
---
 editors/sed.c | 57 ++++++++++++++++++++++++++++++++-------------------
 1 file changed, 36 insertions(+), 21 deletions(-)

diff --git a/editors/sed.c b/editors/sed.c
index 9d14294fb..4dd89fa8d 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -1528,7 +1528,7 @@ static void add_cmd_block(char *cmdstr)
 int sed_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int sed_main(int argc UNUSED_PARAM, char **argv)
 {
-	unsigned opt, i;
+	unsigned opt;
 	llist_t *opt_e, *opt_f;
 	char *opt_i;
 
@@ -1568,36 +1568,51 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
 			sed_longopts,
 			&opt_i, &opt_e, &opt_f,
 			&G.be_quiet); /* counter for -n */
-
-
-	/* Process -e and -f options in command line order.
-	 * getopt32long stores them in separate lists, losing
-	 * their relative order. We re-scan argv to preserve it.
+	/*
+	 * RAF: process -e and -f options in command line order.
+	 * The getopt32long stores them in separate lists, losing
+	 * their relative order. We determine which appeared first
+	 * by finding which argv[] element each optarg points into.
 	 */
-	for (i = 1; i < optind; i++)
-	{
-		char *p = argv[i], c = *p;
-		if (c != '-' || !*++p) //'-'
-			continue;
-		if (*p == '-' && !*++p) //'--'
-			continue;
-		c = *p;
-		if (c == 'e' && opt_e) {
-			add_cmd_block(llist_pop(&opt_e));
+	while (opt_e || opt_f) {
+		int use_e = 1;
+		if (opt_e && opt_f) {
+			int i, idx_e = optind, idx_f = optind;
+			for (i = 1; i < optind; i++) {
+				char *end = argv[i] + strlen(argv[i]);
+				if (idx_e == optind
+				&&  opt_e->data >= argv[i]
+				&&  opt_e->data <= end
+				){
+					idx_e = i;
+				}
+				if (idx_f == optind
+				&&  opt_f->data >= argv[i]
+				&&  opt_f->data <= end
+				){
+					idx_f = i;
+				}
+			}
+			if (idx_f < idx_e) {
+				use_e = 0;
+			}
 		}
 		else
-		if (c == 'f' && opt_f) {
+		if (!opt_e) {
+			use_e = 0;
+		}
+		if (use_e) {
+			add_cmd_block(llist_pop(&opt_e));
+		} else {
 			char *line;
 			FILE *cmdfile = xfopen_stdin(llist_pop(&opt_f));
-			while ( (line = xmalloc_fgetline(cmdfile)) ) {
+			while ((line = xmalloc_fgetline(cmdfile)) != NULL) {
 				add_cmd(line);
 				free(line);
 			}
 			fclose_if_not_stdin(cmdfile);
-		}
+ 		}
 	}
-	llist_free(opt_e, free);
-	llist_free(opt_f, free);
 
 	//argc -= optind;
 	argv += optind;
-- 
2.34.1

From d1f50a14db96968d4ecc1cb042dfb83bd2cd6a01 Mon Sep 17 00:00:00 2001
From: "Roberto A. Foglietta" <[email protected]>
Date: Mon, 17 Aug 2026 07:38:13 +0200
Subject: [PATCH 1/9] sed.c: POSIX compliance fix about '-f' with '-e' ordered
 options v2

bug found:

- https://savannah.gnu.org/bugs/?68601

fix size:

   text    data     bss     dec     hex filename
   7352       0       0    7352    1cb8 editors/sed.o
   7441       0       0    7441    1d11 editors/sed.o v1
   7465       0       0    7465    1d29 editors/sed.o v2
                           +113

regression:

- what about -nre? or -nve? uncommon but lecit and broken

Signed-off-by: Roberto A. Foglietta <[email protected]>
---
 editors/sed.c | 47 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 33 insertions(+), 14 deletions(-)

diff --git a/editors/sed.c b/editors/sed.c
index 029e9b8e7..9d14294fb 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -1528,7 +1528,7 @@ static void add_cmd_block(char *cmdstr)
 int sed_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int sed_main(int argc UNUSED_PARAM, char **argv)
 {
-	unsigned opt;
+	unsigned opt, i;
 	llist_t *opt_e, *opt_f;
 	char *opt_i;
 
@@ -1568,6 +1568,37 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
 			sed_longopts,
 			&opt_i, &opt_e, &opt_f,
 			&G.be_quiet); /* counter for -n */
+
+
+	/* Process -e and -f options in command line order.
+	 * getopt32long stores them in separate lists, losing
+	 * their relative order. We re-scan argv to preserve it.
+	 */
+	for (i = 1; i < optind; i++)
+	{
+		char *p = argv[i], c = *p;
+		if (c != '-' || !*++p) //'-'
+			continue;
+		if (*p == '-' && !*++p) //'--'
+			continue;
+		c = *p;
+		if (c == 'e' && opt_e) {
+			add_cmd_block(llist_pop(&opt_e));
+		}
+		else
+		if (c == 'f' && opt_f) {
+			char *line;
+			FILE *cmdfile = xfopen_stdin(llist_pop(&opt_f));
+			while ( (line = xmalloc_fgetline(cmdfile)) ) {
+				add_cmd(line);
+				free(line);
+			}
+			fclose_if_not_stdin(cmdfile);
+		}
+	}
+	llist_free(opt_e, free);
+	llist_free(opt_f, free);
+
 	//argc -= optind;
 	argv += optind;
 	if (opt & OPT_in_place) { // -i
@@ -1577,19 +1608,7 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
 		G.regex_type |= REG_EXTENDED; // -r or -E
 	//if (opt & 8)
 	//	G.be_quiet++; // -n (implemented with a counter instead)
-	while (opt_e) { // -e
-		add_cmd_block(llist_pop(&opt_e));
-	}
-	while (opt_f) { // -f
-		char *line;
-		FILE *cmdfile;
-		cmdfile = xfopen_stdin(llist_pop(&opt_f));
-		while ((line = xmalloc_fgetline(cmdfile)) != NULL) {
-			add_cmd(line);
-			free(line);
-		}
-		fclose_if_not_stdin(cmdfile);
-	}
+
 	/* if we didn't get a pattern from -e or -f, use argv[0] */
 	if (!(opt & 0x30)) {
 		if (!*argv)
-- 
2.34.1

  • ... G. Branden Robinson
    • ... Bruno Haible via discussion of the GNU roff typesetting system and related software
      • ... G. Branden Robinson
      • ... Bruno Haible via discussion of the GNU roff typesetting system and related software
        • ... G. Branden Robinson
          • ... Roberto A. Foglietta
            • ... G. Branden Robinson
          • ... Roberto A. Foglietta
            • ... Roberto A. Foglietta
          • ... Rob Landley
            • ... Roberto A. Foglietta
              • ... Roberto A. Foglietta
    • ... Bruno Haible via discussion of the GNU roff typesetting system and related software
    • ... Bruno Haible via discussion of the GNU roff typesetting system and related software
    • ... Bruno Haible via discussion of the GNU roff typesetting system and related software
    • ... Bruno Haible via discussion of the GNU roff typesetting system and related software
    • ... Bruno Haible via discussion of the GNU roff typesetting system and related software
      • ... G. Branden Robinson
        • ... Bruno Haible via discussion of the GNU roff typesetting system and related software
          • ... G. Branden Robinson
            • ... Bruno Haible via discussion of the GNU roff typesetting system and related software

Reply via email to