Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package dash for openSUSE:Factory checked in 
at 2026-10-03 20:13:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/dash (Old)
 and      /work/SRC/openSUSE:Factory/.dash.new.1631729 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "dash"

Sat Oct  3 20:13:07 2026 rev:34 rq:1382147 version:0.5.13.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/dash/dash.changes        2026-06-29 
17:30:49.670991487 +0200
+++ /work/SRC/openSUSE:Factory/.dash.new.1631729/dash.changes   2026-10-03 
20:13:08.479616987 +0200
@@ -1,0 +2,23 @@
+Fri Oct  2 15:46:12 UTC 2026 - Dirk Müller <[email protected]>
+
+- add CVE-2026-102474.patch (bsc#1283151, CVE-2026-102474)
+
+-------------------------------------------------------------------
+Tue Sep 29 14:14:41 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 0.5.13.5:
+  * builtin: Add CTLESC before all CCTLs in dollar single quote
+  * input: Fix overeager NUL deletion in SMALL mode
+  * var: Call setlocale when LC variables are set
+  * var: Remove unset check in varnull
+  * var: Restore double NUL on unset variables
+  * parser: Do not print prompt if input buffer is not empty
+  * parser: Use USTPUTC in parsebackq
+  * parser: Print escapes for command substitution in EOF marker
+  * parser: Clamp backslash-c sequences to 7 bits
+  * man: Use proper grave accent character
+  * man: Use literal > and < characters
+  * builtin: Fix unaligned access in conv_escape
+  * builtin: Fix octal escapes in dollar-single-quotes
+
+-------------------------------------------------------------------
@@ -4 +27 @@
-- update to 0.15.3.4 (bsc#1269494, CVE-2026-31323):
+- update to 0.5.13.4 (bsc#1269494, CVE-2026-31323):
@@ -19 +42 @@
-- Update to 0.15.3.1
+- Update to 0.5.13.1

Old:
----
  dash-0.5.13.4.tar.gz

New:
----
  CVE-2026-102474.patch
  dash-0.5.13.5.tar.gz

----------(New B)----------
  New:
- add CVE-2026-102474.patch (bsc#1283151, CVE-2026-102474)
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ dash.spec ++++++
--- /var/tmp/diff_new_pack.IjrxeX/_old  2026-10-03 20:13:09.282650610 +0200
+++ /var/tmp/diff_new_pack.IjrxeX/_new  2026-10-03 20:13:09.284650694 +0200
@@ -18,13 +18,14 @@
 
 
 Name:           dash
-Version:        0.5.13.4
+Version:        0.5.13.5
 Release:        0
 Summary:        POSIX-compliant Implementation of /bin/sh
 License:        BSD-3-Clause AND GPL-2.0-or-later
 Group:          System/Shells
 URL:            http://gondor.apana.org.au/~herbert/dash/
 Source0:        
http://gondor.apana.org.au/~herbert/dash/files/%{name}-%{version}.tar.gz
+Patch1:         CVE-2026-102474.patch
 BuildRequires:  pkgconfig
 BuildRequires:  pkgconfig(libedit)
 

++++++ CVE-2026-102474.patch ++++++
--- dash-0.5.13.5/src/bltin/printf.c
+++ dash-0.5.13.5/src/bltin/printf.c
@@ -169,7 +169,7 @@
                                char *cp;
 
                                STARTSTACKSTR(cp);
-                               CHECKSTRSPACE(4, cp);
+                               CHECKSTRSPACE(8, cp);
                                ret = conv_escape(fmt, cp, false);
                                fmt += ret >> 4;
                                out1mem(cp, ret & 15);
@@ -290,7 +290,7 @@
                unsigned ret;
                int ch;
 
-               CHECKSTRSPACE(4, cp);
+               CHECKSTRSPACE(8, cp);
 
                c = *str++;
                if (c != '\\') {

++++++ dash-0.5.13.4.tar.gz -> dash-0.5.13.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-0.5.13.4/configure new/dash-0.5.13.5/configure
--- old/dash-0.5.13.4/configure 2026-05-09 04:59:28.000000000 +0200
+++ new/dash-0.5.13.5/configure 2026-07-18 00:24:51.000000000 +0200
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.72 for dash 0.5.13.4.
+# Generated by GNU Autoconf 2.72 for dash 0.5.13.5.
 #
 #
 # Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation,
@@ -601,8 +601,8 @@
 # Identity of this package.
 PACKAGE_NAME='dash'
 PACKAGE_TARNAME='dash'
-PACKAGE_VERSION='0.5.13.4'
-PACKAGE_STRING='dash 0.5.13.4'
+PACKAGE_VERSION='0.5.13.5'
+PACKAGE_STRING='dash 0.5.13.5'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1302,7 +1302,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-'configure' configures dash 0.5.13.4 to adapt to many kinds of systems.
+'configure' configures dash 0.5.13.5 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1369,7 +1369,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of dash 0.5.13.4:";;
+     short | recursive ) echo "Configuration of dash 0.5.13.5:";;
    esac
   cat <<\_ACEOF
 
@@ -1474,7 +1474,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-dash configure 0.5.13.4
+dash configure 0.5.13.5
 generated by GNU Autoconf 2.72
 
 Copyright (C) 2023 Free Software Foundation, Inc.
@@ -1991,7 +1991,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by dash $as_me 0.5.13.4, which was
+It was created by dash $as_me 0.5.13.5, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -3466,7 +3466,7 @@
 
 # Define the identity of the package.
  PACKAGE='dash'
- VERSION='0.5.13.4'
+ VERSION='0.5.13.5'
 
 
 printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -6294,7 +6294,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by dash $as_me 0.5.13.4, which was
+This file was extended by dash $as_me 0.5.13.5, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -6362,7 +6362,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-dash config.status 0.5.13.4
+dash config.status 0.5.13.5
 configured by $0, generated by GNU Autoconf 2.72,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-0.5.13.4/configure.ac 
new/dash-0.5.13.5/configure.ac
--- old/dash-0.5.13.4/configure.ac      2026-05-09 04:55:05.000000000 +0200
+++ new/dash-0.5.13.5/configure.ac      2026-07-18 00:23:59.000000000 +0200
@@ -1,4 +1,4 @@
-AC_INIT([dash],[0.5.13.4])
+AC_INIT([dash],[0.5.13.5])
 AM_INIT_AUTOMAKE([foreign subdir-objects])
 AC_CONFIG_SRCDIR([src/main.c])
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-0.5.13.4/src/bltin/printf.c 
new/dash-0.5.13.5/src/bltin/printf.c
--- old/dash-0.5.13.4/src/bltin/printf.c        2025-10-11 15:07:39.000000000 
+0200
+++ new/dash-0.5.13.5/src/bltin/printf.c        2026-07-18 00:15:01.000000000 
+0200
@@ -56,6 +56,7 @@
 
 #include "bltin.h"
 #include "parser.h"
+#include "syntax.h"
 #include "system.h"
 
 #define PF(f, func) { \
@@ -332,6 +333,7 @@
        char *out = out0;
        char *str = str0;
        unsigned value;
+       int och;
        int ch;
 
        ch = *str;
@@ -349,7 +351,7 @@
 
                value = '\\';
 
-               if (isodigit(ch)) {
+               if (unlikely(isodigit(ch))) {
                        ch = 3;
                        value = 0;
                        do {
@@ -359,12 +361,22 @@
                }
 
                str--;
+
+check_value:
+               if (SQSYNTAX[(signed char)value] != CCTL)
+                       break;
+               /* fall through */
+
+       case '\\':
+               if (mbchar)
+                       USTPUTC(CTLESC, out);
                break;
 
        case 'x':
                ch = 2;
 
 hex:
+               och = ch;
                value = 0;
                do {
                        int c = *++str;
@@ -388,8 +400,11 @@
                        value += d;
                } while (--ch);
 
+               if (och <= 2)
+                       goto check_value;
+
                if (value < 0x80)
-                       break;
+                       goto check_value;
 
                if (value < 0x110000) {
                        int mboff = (mbchar - 1) * 2;
@@ -419,7 +434,7 @@
                        USTPUTC(CTLMBCHAR, out);
                        USTPUTC(len, out);
                        STADJUST(mboff, out);
-                       *(uint32_t *)out = value;
+                       memcpy(out, &value, 4);
                        STADJUST(len, out);
                        USTPUTC(len, out);
                        USTPUTC(CTLMBCHAR, out);
@@ -432,9 +447,6 @@
                ch = 4;
                goto hex;
 
-       case '\\':
-               break;
-
        case 'a':                               /* alert */
        case 'b':                               /* backspace */
        case 'f':                               /* form-feed */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-0.5.13.4/src/dash.1 new/dash-0.5.13.5/src/dash.1
--- old/dash-0.5.13.4/src/dash.1        2025-09-23 13:07:58.000000000 +0200
+++ new/dash-0.5.13.5/src/dash.1        2026-06-07 07:20:12.000000000 +0200
@@ -197,7 +197,7 @@
 set from the remaining argument operands.
 .It Fl C Em noclobber
 Don't overwrite existing files with
-.Dq \*[Gt] .
+.Dq > .
 .It Fl e Em errexit
 If not interactive, exit immediately if any untested command fails.
 The exit status of a command is considered to be
@@ -268,9 +268,9 @@
 Following is a list of operators:
 .Bl -ohang -offset indent
 .It "Control operators:"
-.Dl &  &&  \&(  \&)  \&;  ;; | || \*[Lt]newline\*[Gt]
+.Dl &  &&  \&(  \&)  \&;  ;; | || <newline>
 .It "Redirection operators:"
-.Dl \*[Lt]  \*[Gt]  \*[Gt]|  \*[Lt]\*[Lt]  \*[Gt]\*[Gt]  \*[Lt]&  \*[Gt]&  
\*[Lt]\*[Lt]-  \*[Lt]\*[Gt]
+.Dl <  >  >|  <<  >>  <&  >&  <<-  <>
 .El
 .Ss Quoting
 Quoting is used to remove the special meaning of certain characters or
@@ -293,12 +293,12 @@
 meaning of all characters except dollarsign
 .Pq $ ,
 backquote
-.Pq ` ,
+.Pq \(ga ,
 and backslash
 .Pq \e .
 The backslash inside double quotes is historically weird, and serves to
 quote only the following characters:
-.Dl $  `  \*q  \e  \*[Lt]newline\*[Gt] .
+.Dl $  \(ga  \*q  \e  <newline> .
 Otherwise it remains literal.
 .Ss Reserved Words
 Reserved words are words that have special meaning to the
@@ -391,25 +391,25 @@
 .Sq Bq 3 ) ,
 that refers to a file descriptor.
 .Bl -tag -width aaabsfiles -offset indent
-.It [n] Ns \*[Gt] file
+.It [n] Ns > file
 Redirect standard output (or n) to file.
-.It [n] Ns \*[Gt]| file
+.It [n] Ns >| file
 Same, but override the
 .Fl C
 option.
-.It [n] Ns \*[Gt]\*[Gt] file
+.It [n] Ns >> file
 Append standard output (or n) to file.
-.It [n] Ns \*[Lt] file
+.It [n] Ns < file
 Redirect standard input (or n) from file.
-.It [n1] Ns \*[Lt]& Ns n2
+.It [n1] Ns <& Ns n2
 Copy file descriptor n2 as stdin (or fd n1).
-.It [n] Ns \*[Lt]&-
+.It [n] Ns <&-
 Close standard input (or n).
-.It [n1] Ns \*[Gt]& Ns n2
+.It [n1] Ns >& Ns n2
 Copy file descriptor n2 as stdout (or fd n1).
-.It [n] Ns \*[Gt]&-
+.It [n] Ns >&-
 Close standard output (or n).
-.It [n] Ns \*[Lt]\*[Gt] file
+.It [n] Ns <> file
 Open file for reading and writing on standard input (or n).
 .El
 .Pp
@@ -417,7 +417,7 @@
 .Dq here-document .
 .Bl -item -offset indent
 .It
-.Li [n]\*[Lt]\*[Lt] delimiter
+.Li [n]<< delimiter
 .Dl here-doc-text ...
 .Li delimiter
 .El
@@ -431,9 +431,9 @@
 expansion (as described in the section on
 .Dq Expansions ) .
 If the operator is
-.Dq \*[Lt]\*[Lt]-
+.Dq <<-
 instead of
-.Dq \*[Lt]\*[Lt] ,
+.Dq << ,
 then leading tabs in the here-doc-text are stripped.
 .Ss Search and Execution
 There are three types of commands: shell functions, builtin commands, and
@@ -567,7 +567,7 @@
 takes place before redirection, it can be modified by redirection.
 For example:
 .Pp
-.Dl $ command1 2\*[Gt]&1 | command2
+.Dl $ command1 2>&1 | command2
 .Pp
 sends both the standard output and standard error of command1
 to the standard input of command2.
@@ -698,7 +698,7 @@
 their output as though they were one program:
 .\".Pp
 .Bd -literal -offset indent
-{ printf \*q hello \*q ; printf \*q world\\n" ; } \*[Gt] greeting
+{ printf \*q hello \*q ; printf \*q world\\n" ; } > greeting
 .Ed
 .Pp
 Note that
@@ -764,7 +764,7 @@
 A parameter can also be denoted by a number or a special
 character as explained below.
 .Ss Positional Parameters
-A positional parameter is a parameter denoted by a number (n \*[Gt] 0).
+A positional parameter is a parameter denoted by a number (n > 0).
 The shell sets these initially to the values of its command line arguments
 that follow the name of the shell script.
 The
@@ -983,7 +983,7 @@
 version
 .Pc :
 .Pp
-.Dl `command`
+.Dl \(gacommand\(ga
 .Pp
 The shell expands the command substitution by executing command in a
 subshell environment and replacing the command substitution with the
@@ -1627,19 +1627,19 @@
 The characters and their meanings are as follows:
 .Bl -tag -width Ds -offset indent
 .It Cm \ea
-Write a \*[Lt]bell\*[Gt] character.
+Write a <bell> character.
 .It Cm \eb
-Write a \*[Lt]backspace\*[Gt] character.
+Write a <backspace> character.
 .It Cm \ef
-Write a \*[Lt]form-feed\*[Gt] character.
+Write a <form-feed> character.
 .It Cm \en
-Write a \*[Lt]new-line\*[Gt] character.
+Write a <new-line> character.
 .It Cm \er
-Write a \*[Lt]carriage return\*[Gt] character.
+Write a <carriage return> character.
 .It Cm \et
-Write a \*[Lt]tab\*[Gt] character.
+Write a <tab> character.
 .It Cm \ev
-Write a \*[Lt]vertical tab\*[Gt] character.
+Write a <vertical tab> character.
 .It Cm \e\e
 Write a backslash character.
 .It Cm \e Ns Ar num
@@ -2062,13 +2062,13 @@
 and
 .Ar \&s\&2
 are not identical.
-.It Ar \&s\&1 Cm \&\*[Lt] Ar \&s\&2
+.It Ar \&s\&1 Cm \&< Ar \&s\&2
 True if string
 .Ar \&s\&1
 comes before
 .Ar \&s\&2
 based on the ASCII value of their characters.
-.It Ar \&s\&1 Cm \&\*[Gt] Ar \&s\&2
+.It Ar \&s\&1 Cm \&> Ar \&s\&2
 True if string
 .Ar \&s\&1
 comes after
@@ -2380,7 +2380,7 @@
 .Dq #\  .
 .It Ev PS2
 The secondary prompt string, which defaults to
-.Dq \*[Gt]\  .
+.Dq >\  .
 .It Ev PS4
 Output before each line when execution trace (set -x) is enabled,
 defaults to
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-0.5.13.4/src/input.c 
new/dash-0.5.13.5/src/input.c
--- old/dash-0.5.13.4/src/input.c       2026-05-09 04:54:18.000000000 +0200
+++ new/dash-0.5.13.5/src/input.c       2026-07-05 07:17:02.000000000 +0200
@@ -217,39 +217,47 @@
 }
 
 
-static int __pgetc(void)
+/*
+ * Read a character from the script, returning PEOF on end of file.
+ * Nul characters in the input are silently discarded.
+ */
+
+int __attribute__((noinline)) pgetc(void)
 {
+       struct strpush *sp = parsefile->spfree;
        int c;
 
+       if (unlikely(sp))
+               freestrings(sp);
+
+again:
        if (parsefile->unget) {
                long unget = -(long)(unsigned)parsefile->unget--;
 
-               return parsefile->nextc[unget];
+               return (signed char)parsefile->nextc[unget];
        }
 
-       if (parsefile->nleft > 0) {
+nextc:
+       if (likely(parsefile->nleft > 0)) {
                parsefile->nleft--;
                c = (signed char)*parsefile->nextc++;
+       } else if (unlikely(parsefile->strpush)) {
+               popstring();
+               /* The freestrings call must be delayed til the next
+                * pgetc call for PEOA to work properly.
+                */
+               goto again;
        } else
                c = preadbuffer();
 
-       return c;
-}
-
-
-/*
- * Read a character from the script, returning PEOF on end of file.
- * Nul characters in the input are silently discarded.
- */
-
-int __attribute__((noinline)) pgetc(void)
-{
-       struct strpush *sp = parsefile->spfree;
-
-       if (unlikely(sp))
-               freestrings(sp);
+       /* delete nul characters */
+       if (IS_DEFINED_SMALL && unlikely(!c)) {
+               parsefile->nextc = memmove(parsefile->nextc - 1,
+                                          parsefile->nextc, parsefile->nleft);
+               goto nextc;
+       }
 
-       return __pgetc();
+       return c;
 }
 
 int pgetc_eoa(void)
@@ -374,10 +382,6 @@
        int more;
        char *q;
 
-       if (unlikely(parsefile->strpush)) {
-               popstring();
-               return __pgetc();
-       }
        if (parsefile->eof & 2) {
 eof:
                parsefile->eof = 3;
@@ -408,6 +412,12 @@
                }
        }
 
+       if (IS_DEFINED_SMALL) {
+               q += more;
+               more = 0;
+               goto done;
+       }
+
        /* delete nul characters */
        for (;;) {
                int c;
@@ -422,9 +432,6 @@
 
                q++;
 
-               if (IS_DEFINED_SMALL)
-                       goto check;
-
                switch (c) {
                case '\n':
                        goto done;
@@ -439,11 +446,8 @@
                }
 
 check:
-               if (more <= 0) {
-                       if (!IS_DEFINED_SMALL)
-                               goto again;
-                       break;
-               }
+               if (more <= 0)
+                       goto again;
        }
 done:
        input_set_lleft(parsefile, more);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-0.5.13.4/src/jobs.c new/dash-0.5.13.5/src/jobs.c
--- old/dash-0.5.13.4/src/jobs.c        2026-03-21 09:56:03.000000000 +0100
+++ new/dash-0.5.13.5/src/jobs.c        2026-06-13 03:49:51.000000000 +0200
@@ -1264,20 +1264,13 @@
 {
        char *name;
 
-       STARTSTACKSTR(name);
-       commandtextcont(n, name);
+       STARTSTACKSTR(cmdnextc);
+       cmdtxt(n);
        name = stackblock();
        TRACE(("commandtext: name %p, end %p\n", name, cmdnextc));
        return savestr(name);
 }
 
-char *commandtextcont(union node *n, char *next)
-{
-       cmdnextc = next;
-       cmdtxt(n);
-       return cmdnextc;
-}
-
 STATIC void
 cmdtxt(union node *n)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-0.5.13.4/src/jobs.h new/dash-0.5.13.5/src/jobs.h
--- old/dash-0.5.13.4/src/jobs.h        2026-03-16 02:45:46.000000000 +0100
+++ new/dash-0.5.13.5/src/jobs.h        2026-06-13 03:49:51.000000000 +0200
@@ -107,7 +107,6 @@
 struct job *vforkexec(union node *n, char **argv, const char *path, int idx);
 int waitforjob(struct job *);
 int stoppedjobs(void);
-char *commandtextcont(union node *n, char *next);
 
 #if ! JOBS
 #define setjobctl(on) ((void)(on))     /* do nothing */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-0.5.13.4/src/main.c new/dash-0.5.13.5/src/main.c
--- old/dash-0.5.13.4/src/main.c        2025-09-23 13:07:58.000000000 +0200
+++ new/dash-0.5.13.5/src/main.c        2026-06-18 14:01:01.000000000 +0200
@@ -32,7 +32,6 @@
  * SUCH DAMAGE.
  */
 
-#include <locale.h>
 #include <stdio.h>
 #include <signal.h>
 #include <sys/stat.h>
@@ -104,8 +103,6 @@
        monitor(4, etext, profile_buf, sizeof profile_buf, 50);
 #endif
 
-       setlocale(LC_ALL, "");
-
        state = 0;
        if (unlikely(setjmp(main_handler.loc))) {
                int e;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-0.5.13.4/src/parser.c 
new/dash-0.5.13.5/src/parser.c
--- old/dash-0.5.13.4/src/parser.c      2026-05-09 04:54:18.000000000 +0200
+++ new/dash-0.5.13.5/src/parser.c      2026-06-13 03:50:04.000000000 +0200
@@ -92,6 +92,7 @@
        int innerdq;
        int varpushed;
        int dblquote;
+       int backq;              /* Inside back quotes (here-doc word only). */
        int varnest;            /* levels of variables expansion */
        int parenlevel;         /* levels of parens in arithmetic */
        int dqvarnest;          /* levels of variables expansion within double 
quotes */
@@ -968,7 +969,7 @@
 
                p += !((c ^ *p) | (c ^ '\\'));
 
-               conv_ch = (c & ~((c & 0x40) >> 1)) ^ 0x40;
+               conv_ch = (c & ~((c & 0x40) >> 1) & 0x7f) ^ 0x40;
                USTPUTC(conv_ch, out);
        }
 
@@ -1004,7 +1005,7 @@
        };
        int chkeofmark = checkkwd & CHKEOFMARK;
        struct synstack *synstack = &synbase;
-       bool sqheredoc = syntax == SQSYNTAX;
+       bool printesc = syntax == SQSYNTAX;
        struct nodelist *bqlist = NULL;
        int dollarsq = 0;
        int c = firstc;
@@ -1035,9 +1036,10 @@
                        CHECKSTRSPACE((MB_LEN_MAX > 16 ? MB_LEN_MAX : 16) + 7,
                                      out);
                        fieldsplitting = synstack->syntax == BASESYNTAX &&
-                                        !synstack->varnest ? 4 : 0;
+                                        !(synstack->varnest |
+                                          synstack->backq) ? 4 : 0;
                        ml = getmbc(c, out, fieldsplitting |
-                                           (sqheredoc ? 2 : 0));
+                                           (printesc ? 2 : 0));
                        if (ml == 1) {
                                if (out == stackblock())
                                        return TBLANK;
@@ -1079,7 +1081,8 @@
                                }
 
                                if (
-                                       synstack->dblquote &&
+                                       (synstack->dblquote |
+                                        synstack->backq) &&
                                        c != '\\' && c != '`' &&
                                        c != '$' && (
                                                c != '"' ||
@@ -1182,13 +1185,19 @@
                                USTPUTC(c, out);
                                break;
                        case CBQUOTE:   /* '`' */
+                               if (synstack->backq == 2)
+                                       goto end_backq;
                                USTPUTC('`', out);
                                PARSEBACKQOLD();
                                break;
                        case CEOF:
                                goto endword;           /* exit outer loop */
                        default:
-                               if (fieldsplitting)
+                               if (c == ')' && synstack->backq == 1) {
+end_backq:
+                                       synstack_pop(&synstack);
+                                       printesc = 0;
+                               } else if (fieldsplitting)
                                        goto endword;   /* exit outer loop */
                                USTPUTC(c, out);
                        }
@@ -1197,7 +1206,8 @@
 endword:
        if (synstack->syntax == ARISYNTAX)
                synerror("Missing '))'");
-       if (synstack->syntax != BASESYNTAX && eofmark == NULL)
+       if ((synstack->syntax != BASESYNTAX && eofmark == NULL) ||
+           synstack->backq)
                synerror("Unterminated quoted string");
        if (synstack->varnest != 0) {
                /* { */
@@ -1520,16 +1530,20 @@
        char *pstr;
        char *str;
 
-       if (!chkeofmark) {
-               STADJUST(oldstyle - 1, out);
-               out[-1] = CTLBACKQ;
-       }
-       if (!chkeofmark || !oldstyle) {
-               str = stackblock();
-               savelen = out - (char *)stackblock();
-               grabstackblock(savelen);
-               STARTSTACKSTR(out);
-       }
+       if (chkeofmark) {
+               synstack_push(&synstack,
+                             synstack->prev ?: alloca(sizeof(*synstack)),
+                             BASESYNTAX);
+               synstack->backq = oldstyle + 1;
+               printesc = 1;
+               goto parsebackq_out;
+       }
+       STADJUST(oldstyle - 1, out);
+       out[-1] = CTLBACKQ;
+       str = stackblock();
+       savelen = out - (char *)stackblock();
+       grabstackblock(savelen);
+       STARTSTACKSTR(out);
         if (oldstyle) {
                 /* We must read until the closing backquote, giving special
                    treatment to some slashes, and then push the string and
@@ -1539,6 +1553,7 @@
                 int pc;
 
                while (!done) {
+                       CHECKSTRSPACE(MB_LEN_MAX + 1, pout);
                        if (needprompt) {
                                setprompt(2);
                        }
@@ -1551,8 +1566,7 @@
                                 pc = pgetc();
                                 if (pc != '\\' && pc != '`' && pc != '$'
                                     && (!synstack->dblquote || pc != '"'))
-                                        STPUTC('\\', pout);
-                               CHECKSTRSPACE(MB_LEN_MAX, pout);
+                                        USTPUTC('\\', pout);
                                ml = getmbc(pc, pout, 2);
                                pout += ml;
                                if (ml)
@@ -1569,12 +1583,8 @@
                        default:
                                break;
                        }
-                       STPUTC(pc, pout);
+                       USTPUTC(pc, pout);
                 }
-               if (chkeofmark) {
-                       out = pout;
-                       goto parsebackq_oldreturn;
-               }
                pout[-1] = 0;
                pstr = grabstackstr(pout);
                setinputstring(pstr);
@@ -1612,6 +1622,7 @@
 
        out = stnputs(str, savelen, stackblock());
 
+parsebackq_out:
        if (oldstyle) {
                /* Ignore any pushed back tokens left from the backquote
                 * parsing.
@@ -1619,10 +1630,6 @@
                tokpushback = 0;
                goto parsebackq_oldreturn;
        } else {
-               if (chkeofmark) {
-                       out = commandtextcont(n, out);
-                       STPUTC(')', out);
-               }
                goto parsebackq_newreturn;
        }
 }
@@ -1705,8 +1712,7 @@
        /* NOTREACHED */
 }
 
-STATIC void
-setprompt(int which)
+static void __attribute__((noinline)) setprompt(int which)
 {
        struct stackmark smark;
        int show;
@@ -1719,7 +1725,7 @@
 #else
        show = !el;
 #endif
-       if (show) {
+       if (show && !parsefile->nleft) {
                pushstackmark(&smark, stackblocksize());
                out2str(getprompt(NULL));
                popstackmark(&smark);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-0.5.13.4/src/var.c new/dash-0.5.13.5/src/var.c
--- old/dash-0.5.13.4/src/var.c 2025-09-23 13:07:58.000000000 +0200
+++ new/dash-0.5.13.5/src/var.c 2026-06-18 14:01:01.000000000 +0200
@@ -32,6 +32,7 @@
  * SUCH DAMAGE.
  */
 
+#include <locale.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -81,6 +82,12 @@
 int lineno;
 char linenovar[sizeof("LINENO=")+sizeof(int)*CHAR_BIT/3+1] = "LINENO=";
 
+static void changelocale(const char *val)
+{
+       putenv((char *)val);
+       setlocale(LC_ALL, nullstr);
+}
+
 /* Some macros in var.h depend on the order, add new variables to the end. */
 struct var varinit[] = {
 #if ATTY
@@ -101,6 +108,11 @@
        { 0,    VSTRFIXED|VTEXTFIXED|VUNSET,    "TERM\0",       0 },
        { 0,    VSTRFIXED|VTEXTFIXED|VUNSET,    "HISTSIZE\0",   sethistsize },
 #endif
+       { 0,    VSTRFIXED|VTEXTFIXED|VFULL|VUNSET, "LC_ALL\0",  changelocale },
+       { 0,    VSTRFIXED|VTEXTFIXED|VFULL|VUNSET, "LC_COLLATE\0", changelocale 
},
+       { 0,    VSTRFIXED|VTEXTFIXED|VFULL|VUNSET, "LC_CTYPE\0", changelocale },
+       { 0,    VSTRFIXED|VTEXTFIXED|VFULL|VUNSET, "LC_NUMERIC\0", changelocale 
},
+       { 0,    VSTRFIXED|VTEXTFIXED|VFULL|VUNSET, "LANG\0",    changelocale },
 };
 
 STATIC struct var *vartab[VTABSIZE];
@@ -156,7 +168,21 @@
 
 static char *varnull(const char *s)
 {
-       return (strchr(s, '=') ?: nullstr - 1) + 1;
+       /* Unset variables always end with two NUL chars. */
+       return strchrnul(s, '=') + 1;
+}
+
+static void varfunc(struct var *vp)
+{
+       const char *s;
+
+       if (!vp->func)
+               return;
+
+       s = vp->text;
+       if (!(vp->flags & VFULL))
+               s = varnull(s);
+       (*vp->func)(s);
 }
 
 /*
@@ -210,9 +236,9 @@
                vallen = strlen(val);
        }
        INTOFF;
-       p = mempcpy(nameeq = ckmalloc(namelen + vallen + 2), name, namelen);
+       p = mempcpy(nameeq = ckmalloc(namelen + vallen + 2), name, namelen + 1);
        if (val) {
-               *p++ = '=';
+               p[-1] = '=';
                p = mempcpy(p, val, vallen);
        }
        *p = '\0';
@@ -298,8 +324,8 @@
        vp->text = s;
        vp->flags = flags;
 
-       if (vp->func && (flags & VNOFUNC) == 0)
-               (*vp->func)(varnull(s));
+       if (!(flags & VNOFUNC))
+               varfunc(vp);
 
 out:
        return vp;
@@ -535,8 +561,8 @@
                                ckfree(vp->text);
                        vp->flags = lvp->flags;
                        vp->text = lvp->text;
-                       if (vp->func && !(vp->flags & VNOFUNC))
-                               (*vp->func)(varnull(vp->text));
+                       if (!(vp->flags & VNOFUNC))
+                               varfunc(vp);
                }
                ckfree(lvp);
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/dash-0.5.13.4/src/var.h new/dash-0.5.13.5/src/var.h
--- old/dash-0.5.13.4/src/var.h 2025-09-23 13:07:58.000000000 +0200
+++ new/dash-0.5.13.5/src/var.h 2026-06-18 14:01:01.000000000 +0200
@@ -48,7 +48,7 @@
 #define VSTACK         0x10    /* text is allocated on the stack */
 #define VUNSET         0x20    /* the variable is not set */
 #define VNOFUNC                0x40    /* don't call the callback function */
-/* #define VNOSET      0x80       do not set variable - just readonly test */
+#define VFULL          0x80    /* pass value suitable for putenv */
 #define VNOSAVE                0x100   /* when text is on the heap before 
setvareq */
 
 

Reply via email to