From owner-svn-src-all@FreeBSD.ORG Wed Oct 13 23:29:10 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5AC811065672; Wed, 13 Oct 2010 23:29:10 +0000 (UTC) (envelope-from obrien@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 480738FC13; Wed, 13 Oct 2010 23:29:10 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o9DNTAmX004224; Wed, 13 Oct 2010 23:29:10 GMT (envelope-from obrien@svn.freebsd.org) Received: (from obrien@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o9DNTAGq004219; Wed, 13 Oct 2010 23:29:10 GMT (envelope-from obrien@svn.freebsd.org) Message-Id: <201010132329.o9DNTAGq004219@svn.freebsd.org> From: "David E. O'Brien" Date: Wed, 13 Oct 2010 23:29:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r213814 - in head: bin/sh tools/regression/bin/sh/expansion X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Oct 2010 23:29:10 -0000 Author: obrien Date: Wed Oct 13 23:29:09 2010 New Revision: 213814 URL: http://svn.freebsd.org/changeset/base/213814 Log: Do not assume in growstackstr() that a "precious" character will be immediately written into the stack after the call. Instead let the caller manage the "space left". Previously, growstackstr()'s assumption causes problems with STACKSTRNUL() where we want to be able to turn a stack into a C string, and later pretend the NUL is not there. This fixes a bug in STACKSTRNUL() (that grew the stack) where: 1. STADJUST() called after a STACKSTRNUL() results in an improper adjust. This can be seen in ${var%pattern} and ${var%%pattern} evaluation. 2. Memory leak in STPUTC() called after a STACKSTRNUL(). Reviewed by: jilles Added: head/tools/regression/bin/sh/expansion/trim4.0 (contents, props changed) Modified: head/bin/sh/histedit.c head/bin/sh/memalloc.c head/bin/sh/memalloc.h Modified: head/bin/sh/histedit.c ============================================================================== --- head/bin/sh/histedit.c Wed Oct 13 22:59:04 2010 (r213813) +++ head/bin/sh/histedit.c Wed Oct 13 23:29:09 2010 (r213814) @@ -418,7 +418,7 @@ fc_replace(const char *s, char *p, char } else STPUTC(*s++, dest); } - STACKSTRNUL(dest); + STPUTC('\0', dest); dest = grabstackstr(dest); return (dest); Modified: head/bin/sh/memalloc.c ============================================================================== --- head/bin/sh/memalloc.c Wed Oct 13 22:59:04 2010 (r213813) +++ head/bin/sh/memalloc.c Wed Oct 13 23:29:09 2010 (r213814) @@ -295,6 +295,13 @@ grabstackblock(int len) * is space for at least one character. */ +static char * +growstrstackblock(int n) +{ + growstackblock(); + sstrnleft = stackblocksize() - n; + return stackblock() + n; +} char * growstackstr(void) @@ -304,12 +311,10 @@ growstackstr(void) len = stackblocksize(); if (herefd >= 0 && len >= 1024) { xwrite(herefd, stackblock(), len); - sstrnleft = len - 1; + sstrnleft = len; return stackblock(); } - growstackblock(); - sstrnleft = stackblocksize() - len - 1; - return stackblock() + len; + return growstrstackblock(len); } @@ -323,9 +328,7 @@ makestrspace(void) int len; len = stackblocksize() - sstrnleft; - growstackblock(); - sstrnleft = stackblocksize() - len; - return stackblock() + len; + return growstrstackblock(len); } Modified: head/bin/sh/memalloc.h ============================================================================== --- head/bin/sh/memalloc.h Wed Oct 13 22:59:04 2010 (r213813) +++ head/bin/sh/memalloc.h Wed Oct 13 23:29:09 2010 (r213814) @@ -67,9 +67,16 @@ void ungrabstackstr(char *, char *); #define stackblock() stacknxt #define stackblocksize() stacknleft #define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize() -#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c))) +#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), --sstrnleft, *p++ = (c))) #define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(); } #define USTPUTC(c, p) (--sstrnleft, *p++ = (c)) +/* + * STACKSTRNUL's use is where we want to be able to turn a stack + * (non-sentinel, character counting string) into a C string, + * and later pretend the NUL is not there. + * Note: Because of STACKSTRNUL's semantics, STACKSTRNUL cannot be used + * on a stack that will grabstackstr()ed. + */ #define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0')) #define STUNPUTC(p) (++sstrnleft, --p) #define STTOPC(p) p[-1] Added: head/tools/regression/bin/sh/expansion/trim4.0 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/regression/bin/sh/expansion/trim4.0 Wed Oct 13 23:29:09 2010 (r213814) @@ -0,0 +1,15 @@ +# $FreeBSD$ + +v1=/homes/SOME_USER +v2= +v3=C123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + +# Trigger bug in VSTRIMRIGHT processing STADJUST() call in expand.c:subevalvar() +while [ ${#v2} -lt 2000 ]; do + v4="${v2} ${v1%/*} $v3" + if [ ${#v4} -ne $((${#v2} + ${#v3} + 8)) ]; then + echo bad: ${#v4} -ne $((${#v2} + ${#v3} + 8)) + fi + v2=x$v2 + v3=y$v3 +done