From nobody@FreeBSD.org  Wed Sep  8 12:22:25 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 6528B10656E0
	for <freebsd-gnats-submit@FreeBSD.org>; Wed,  8 Sep 2010 12:22:25 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 551128FC15
	for <freebsd-gnats-submit@FreeBSD.org>; Wed,  8 Sep 2010 12:22:25 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o88CMN1d081777
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 8 Sep 2010 12:22:23 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o88CMN0j081776;
	Wed, 8 Sep 2010 12:22:23 GMT
	(envelope-from nobody)
Message-Id: <201009081222.o88CMN0j081776@www.freebsd.org>
Date: Wed, 8 Sep 2010 12:22:23 GMT
From: Richard Lowe <richlowe@richlowe.net>
To: freebsd-gnats-submit@FreeBSD.org
Subject: tr mis-parses '[=]=]' equivalence class
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         150384
>Category:       bin
>Synopsis:       [patch] tr(1): tr mis-parses '[=]=]' equivalence class
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    jilles
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Sep 08 12:30:00 UTC 2010
>Closed-Date:    Sun Jul 24 20:24:24 UTC 2011
>Last-Modified:  Sun Jul 24 20:24:24 UTC 2011
>Originator:     Richard Lowe
>Release:        CURRENT
>Organization:
>Environment:
N/A
>Description:
While working on porting the FreeBSD tr(1) to another system, we hit upon an issue reported by a user that tr didn't process '[=]=]' in the way they expected, that is:

  echo '[[[[]]]]' | tr -d '[=]=]'

Would print an empty string, rather than '[[[['

It seems that in bracket(), tr parses the above equivalence class as a character class, '[=]' followed by '=]', due to the call to strchr() finding the central ] when searching for a terminator then finding that the length of the class is less than 4, and punting on it.


>How-To-Repeat:
echo "[[[[]]]]" | tr -d '[=]=]'
Expecting '[[[['
>Fix:
A naive patch, causing bracket() to skip an extra character (that forming the equivalence class) before searching for the terminating ']', is attached.

Patch attached with submission follows:

diff -u /home/richlowe/str.c /tmp/buffer-content-1887OIZ
--- /home/richlowe/str.c	2010-09-08 08:13:18.000000000 -0400
+++ /tmp/buffer-content-1887OIZ	2010-09-08 08:17:36.000000000 -0400
@@ -156,7 +156,7 @@
 		s->str = p + 1;
 		return (1);
 	case '=':				/* "[=equiv=]" */
-		if ((p = strchr(s->str + 2, ']')) == NULL)
+		if ((p = strchr(s->str + 3, ']')) == NULL)
 			return (0);
 		if (*(p - 1) != '=' || p - s->str < 4)
 			goto repeat;

Diff finished.  Wed Sep  8 08:17:36 2010


>Release-Note:
>Audit-Trail:

From: Jilles Tjoelker <jilles@stack.nl>
To: bug-followup@FreeBSD.org, richlowe@richlowe.net
Cc:  
Subject: Re: bin/150384: [patch] tr(1): tr mis-parses '[=]=]' equivalence
 class
Date: Mon, 20 Sep 2010 00:26:57 +0200

 This indeed seems a bug.
 
 The patch, however, introduces another bug: when parsing the string "[="
 it searches for ']' beyond the end of the string. An additional
 condition on s->str[2] is necessary to avoid this.
 
 -- 
 Jilles Tjoelker
State-Changed-From-To: open->patched 
State-Changed-By: jilles 
State-Changed-When: Wed Sep 29 22:27:58 UTC 2010 
State-Changed-Why:  
Applied to 9-current, thanks! 


Responsible-Changed-From-To: freebsd-bugs->jilles 
Responsible-Changed-By: jilles 
Responsible-Changed-When: Wed Sep 29 22:27:58 UTC 2010 
Responsible-Changed-Why:  
Take. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=150384 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/150384: commit references a PR
Date: Wed, 29 Sep 2010 22:24:26 +0000 (UTC)

 Author: jilles
 Date: Wed Sep 29 22:24:18 2010
 New Revision: 213284
 URL: http://svn.freebsd.org/changeset/base/213284
 
 Log:
   tr: Fix '[=]=]' equivalence class.
   
   A closing bracket immediately after '[=' should not be treated as special.
   
   Different from the submitted patch, a string ending with '[=' does not cause
   access beyond the terminating '\0'.
   
   PR:		bin/150384
   Submitted by:	Richard Lowe
   MFC after:	2 weeks
 
 Added:
   head/tools/regression/usr.bin/tr/regress.0c.out   (contents, props changed)
   head/tools/regression/usr.bin/tr/regress.0d.out   (contents, props changed)
 Modified:
   head/tools/regression/usr.bin/tr/regress.sh
   head/usr.bin/tr/str.c
 
 Added: head/tools/regression/usr.bin/tr/regress.0c.out
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/tr/regress.0c.out	Wed Sep 29 22:24:18 2010	(r213284)
 @@ -0,0 +1 @@
 +[[[[
 
 Added: head/tools/regression/usr.bin/tr/regress.0d.out
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/tr/regress.0d.out	Wed Sep 29 22:24:18 2010	(r213284)
 @@ -0,0 +1 @@
 +
 
 Modified: head/tools/regression/usr.bin/tr/regress.sh
 ==============================================================================
 --- head/tools/regression/usr.bin/tr/regress.sh	Wed Sep 29 21:56:31 2010	(r213283)
 +++ head/tools/regression/usr.bin/tr/regress.sh	Wed Sep 29 22:24:18 2010	(r213284)
 @@ -1,6 +1,6 @@
  # $FreeBSD$
  
 -echo 1..12
 +echo 1..14
  
  REGRESSION_START($1)
  
 @@ -16,5 +16,7 @@ REGRESSION_TEST(`08', `tr "[[:upper:]]" 
  REGRESSION_TEST(`09', `printf "\\f\\r\\n" | tr "\\014\\r" "?#"')
  REGRESSION_TEST(`0a', `printf "0xdeadbeef\\n" | tr "x[[:xdigit:]]" "?\$"')
  REGRESSION_TEST(`0b', `(tr -cd "[[:xdigit:]]" < regress2.in ; echo)')
 +REGRESSION_TEST(`0c', `echo "[[[[]]]]" | tr -d "[=]=]"')
 +REGRESSION_TEST(`0d', `echo "]=[" | tr -d "[=]"')
  
  REGRESSION_END()
 
 Modified: head/usr.bin/tr/str.c
 ==============================================================================
 --- head/usr.bin/tr/str.c	Wed Sep 29 21:56:31 2010	(r213283)
 +++ head/usr.bin/tr/str.c	Wed Sep 29 22:24:18 2010	(r213284)
 @@ -156,7 +156,7 @@ bracket(s)
  		s->str = p + 1;
  		return (1);
  	case '=':				/* "[=equiv=]" */
 -		if ((p = strchr(s->str + 2, ']')) == NULL)
 +		if (s->str[2] == '\0' || (p = strchr(s->str + 3, ']')) == NULL)
  			return (0);
  		if (*(p - 1) != '=' || p - s->str < 4)
  			goto repeat;
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/150384: commit references a PR
Date: Fri, 15 Oct 2010 15:37:25 +0000 (UTC)

 Author: jilles
 Date: Fri Oct 15 15:37:16 2010
 New Revision: 213899
 URL: http://svn.freebsd.org/changeset/base/213899
 
 Log:
   MFC r213284: tr: Fix '[=]=]' equivalence class.
   
   A closing bracket immediately after '[=' should not be treated as special.
   
   Different from the submitted patch, a string ending with '[=' does not cause
   access beyond the terminating '\0'.
   
   PR:		bin/150384
   Submitted by:	Richard Lowe
 
 Added:
   stable/8/tools/regression/usr.bin/tr/regress.0c.out
      - copied unchanged from r213284, head/tools/regression/usr.bin/tr/regress.0c.out
   stable/8/tools/regression/usr.bin/tr/regress.0d.out
      - copied unchanged from r213284, head/tools/regression/usr.bin/tr/regress.0d.out
 Modified:
   stable/8/tools/regression/usr.bin/tr/regress.sh
   stable/8/usr.bin/tr/str.c
 Directory Properties:
   stable/8/tools/regression/usr.bin/tr/   (props changed)
   stable/8/usr.bin/tr/   (props changed)
 
 Copied: stable/8/tools/regression/usr.bin/tr/regress.0c.out (from r213284, head/tools/regression/usr.bin/tr/regress.0c.out)
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ stable/8/tools/regression/usr.bin/tr/regress.0c.out	Fri Oct 15 15:37:16 2010	(r213899, copy of r213284, head/tools/regression/usr.bin/tr/regress.0c.out)
 @@ -0,0 +1 @@
 +[[[[
 
 Copied: stable/8/tools/regression/usr.bin/tr/regress.0d.out (from r213284, head/tools/regression/usr.bin/tr/regress.0d.out)
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ stable/8/tools/regression/usr.bin/tr/regress.0d.out	Fri Oct 15 15:37:16 2010	(r213899, copy of r213284, head/tools/regression/usr.bin/tr/regress.0d.out)
 @@ -0,0 +1 @@
 +
 
 Modified: stable/8/tools/regression/usr.bin/tr/regress.sh
 ==============================================================================
 --- stable/8/tools/regression/usr.bin/tr/regress.sh	Fri Oct 15 15:24:59 2010	(r213898)
 +++ stable/8/tools/regression/usr.bin/tr/regress.sh	Fri Oct 15 15:37:16 2010	(r213899)
 @@ -1,6 +1,6 @@
  # $FreeBSD$
  
 -echo 1..12
 +echo 1..14
  
  REGRESSION_START($1)
  
 @@ -16,5 +16,7 @@ REGRESSION_TEST(`08', `tr "[[:upper:]]" 
  REGRESSION_TEST(`09', `printf "\\f\\r\\n" | tr "\\014\\r" "?#"')
  REGRESSION_TEST(`0a', `printf "0xdeadbeef\\n" | tr "x[[:xdigit:]]" "?\$"')
  REGRESSION_TEST(`0b', `(tr -cd "[[:xdigit:]]" < regress2.in ; echo)')
 +REGRESSION_TEST(`0c', `echo "[[[[]]]]" | tr -d "[=]=]"')
 +REGRESSION_TEST(`0d', `echo "]=[" | tr -d "[=]"')
  
  REGRESSION_END()
 
 Modified: stable/8/usr.bin/tr/str.c
 ==============================================================================
 --- stable/8/usr.bin/tr/str.c	Fri Oct 15 15:24:59 2010	(r213898)
 +++ stable/8/usr.bin/tr/str.c	Fri Oct 15 15:37:16 2010	(r213899)
 @@ -156,7 +156,7 @@ bracket(s)
  		s->str = p + 1;
  		return (1);
  	case '=':				/* "[=equiv=]" */
 -		if ((p = strchr(s->str + 2, ']')) == NULL)
 +		if (s->str[2] == '\0' || (p = strchr(s->str + 3, ']')) == NULL)
  			return (0);
  		if (*(p - 1) != '=' || p - s->str < 4)
  			goto repeat;
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: jilles 
State-Changed-When: Sun Jul 24 20:23:09 UTC 2011 
State-Changed-Why:  
This was applied months ago in 9-current and 8-stable, 
no MFC to 7-stable is planned. 
Thanks for the patch. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=150384 
>Unformatted:
