Package: dash
Version: 0.5.12-12
Severity: important
Tags: patch upstream
X-Debbugs-Cc: [email protected]

Dear Maintainer,

dash fails to parse redirect fd numbers > 9. it only recognizes single-digit
fd numbers, which is not spec-compliant, surprising and uncomfortable, since
i now need to add a dependency on bash to something i wanted to ship as
POSIX shell for best compatibility.

Patch is available here:

https://raw.githubusercontent.com/sabotage-linux/sabotage/b659f4cab100156315e073758e15b8b4432692c7/KEEP/dash-redir.patch


-- System Information:
Debian Release: 13.4
  APT prefers stable-security
  APT policy: (500, 'stable-security'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 6.12.74+deb13-amd64 (SMP w/2 CPU threads; PREEMPT)
Locale: LANG=C, LC_CTYPE=C.UTF-8 (charmap=[proxychains] DLL init: 
proxychains-ng 4.17
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 dash depends on:
ii  debianutils  5.23.2
ii  libc6        2.41-12+deb13u2

dash recommends no packages.

dash suggests no packages.

-- debconf information excluded
From: rofl0r <[email protected]>
Date: Thu, 18 Jun 2026 19:40:21 +0000
Subject: [PATCH] dash: fix redirect with fds > 9

When executing e.g. python3 999>debug.log, 999 wasn't recognized as an fd,
but instead passed as a command line argument to python3.

POSIX 2017 clearly states that file descriptors can be longer than a single
digit:

"The number n is an optional one or more digit decimal number designating
the file descriptor number"
https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_07

diff --git a/src/parser.c b/src/parser.c
index 412e876..7e26b5e 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1209,7 +1209,6 @@ endword:
        if (eofmark == NULL) {
                if ((c == '>' || c == '<')
                 && quotef == 0
-                && len <= 2
                 && (*out == '\0' || is_digit(*out))) {
                        PARSEREDIR();
                        return lasttoken = TREDIR;
@@ -1288,12 +1287,20 @@ more_heredoc:
  */
 
 parseredir: {
-       char fd = *out;
+       char *p = out;
        union node *np;
+       int fd = -1;
+
+       while (is_digit(*p) && len--) {
+               if (fd == -1) fd = 0;
+               else fd *= 10;
+               fd += digit_val(*p);
+               ++p;
+       }
 
        np = (union node *)stalloc(sizeof (struct nfile));
        if (c == '>') {
-               np->nfile.fd = 1;
+               np->nfile.fd = fd == -1 ? 1 : fd;
                c = pgetc_eatbnl();
                if (c == '>')
                        np->type = NAPPEND;
@@ -1338,8 +1345,6 @@ parseredir: {
                        break;
                }
        }
-       if (fd != '\0')
-               np->nfile.fd = digit_val(fd);
        redirnode = np;
        goto parseredir_return;
 }
From: rofl0r <[email protected]>
Date: Thu, 18 Jun 2026 19:40:21 +0000
Subject: [PATCH] dash: fix redirect with fds > 9

When executing e.g. python3 999>debug.log, 999 wasn't recognized as an fd,
but instead passed as a command line argument to python3.

POSIX 2017 clearly states that file descriptors can be longer than a single
digit:

"The number n is an optional one or more digit decimal number designating
the file descriptor number"
https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html#tag_19_07

diff --git a/src/parser.c b/src/parser.c
index 412e876..7e26b5e 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1209,7 +1209,6 @@ endword:
        if (eofmark == NULL) {
                if ((c == '>' || c == '<')
                 && quotef == 0
-                && len <= 2
                 && (*out == '\0' || is_digit(*out))) {
                        PARSEREDIR();
                        return lasttoken = TREDIR;
@@ -1288,12 +1287,20 @@ more_heredoc:
  */
 
 parseredir: {
-       char fd = *out;
+       char *p = out;
        union node *np;
+       int fd = -1;
+
+       while (is_digit(*p) && len--) {
+               if (fd == -1) fd = 0;
+               else fd *= 10;
+               fd += digit_val(*p);
+               ++p;
+       }
 
        np = (union node *)stalloc(sizeof (struct nfile));
        if (c == '>') {
-               np->nfile.fd = 1;
+               np->nfile.fd = fd == -1 ? 1 : fd;
                c = pgetc_eatbnl();
                if (c == '>')
                        np->type = NAPPEND;
@@ -1338,8 +1345,6 @@ parseredir: {
                        break;
                }
        }
-       if (fd != '\0')
-               np->nfile.fd = digit_val(fd);
        redirnode = np;
        goto parseredir_return;
 }

Reply via email to