Author: jilles
Date: Thu Feb 27 16:54:43 2014
New Revision: 262565
URL: http://svnweb.freebsd.org/changeset/base/262565

Log:
  sh: Do not corrupt internal representation if LINENO inner expansion fails.
  
  Example:
    f() { : ${LINENO+$((1/0))}; }
  and call this function twice.

Added:
  head/bin/sh/tests/builtins/lineno2.0   (contents, props changed)
Modified:
  head/bin/sh/expand.c
  head/bin/sh/tests/builtins/Makefile

Modified: head/bin/sh/expand.c
==============================================================================
--- head/bin/sh/expand.c        Thu Feb 27 16:07:12 2014        (r262564)
+++ head/bin/sh/expand.c        Thu Feb 27 16:54:43 2014        (r262565)
@@ -672,10 +672,8 @@ evalvar(char *p, int flag)
 again: /* jump here after setting a variable with ${var=text} */
        if (varflags & VSLINENO) {
                set = 1;
-               special = 0;
-               val = var;
-               p[-1] = '\0';   /* temporarily overwrite '=' to have \0
-                                  terminated string */
+               special = 1;
+               val = NULL;
        } else if (special) {
                set = varisset(var, varflags & VSNUL);
                val = NULL;
@@ -704,7 +702,10 @@ again: /* jump here after setting a vari
        if (set && subtype != VSPLUS) {
                /* insert the value of the variable */
                if (special) {
-                       varvalue(var, varflags & VSQUOTE, subtype, flag);
+                       if (varflags & VSLINENO)
+                               STPUTBIN(var, p - var - 1, expdest);
+                       else
+                               varvalue(var, varflags & VSQUOTE, subtype, 
flag);
                        if (subtype == VSLENGTH) {
                                varlenb = expdest - stackblock() - startloc;
                                varlen = varlenb;
@@ -816,7 +817,6 @@ record:
        default:
                abort();
        }
-       p[-1] = '=';    /* recover overwritten '=' */
 
        if (subtype != VSNORMAL) {      /* skip to end of alternative */
                int nesting = 1;

Modified: head/bin/sh/tests/builtins/Makefile
==============================================================================
--- head/bin/sh/tests/builtins/Makefile Thu Feb 27 16:07:12 2014        
(r262564)
+++ head/bin/sh/tests/builtins/Makefile Thu Feb 27 16:54:43 2014        
(r262565)
@@ -87,6 +87,7 @@ FILES+=               hash4.0
 FILES+=                jobid1.0
 FILES+=                jobid2.0
 FILES+=                lineno.0 lineno.0.stdout
+FILES+=                lineno2.0
 FILES+=                local1.0
 FILES+=                local2.0
 FILES+=                local3.0

Added: head/bin/sh/tests/builtins/lineno2.0
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/bin/sh/tests/builtins/lineno2.0        Thu Feb 27 16:54:43 2014        
(r262565)
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+f() {
+       : ${LINENO+${x?}}
+}
+
+unset -v x
+command eval f 2>/dev/null && exit 3
+x=1
+f
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to