Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 Sep 2010 12:22:23 GMT
From:      Richard Lowe <richlowe@richlowe.net>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/150384: tr mis-parses '[=]=]' equivalence class
Message-ID:  <201009081222.o88CMN0j081776@www.freebsd.org>
Resent-Message-ID: <201009081230.o88CU14Q044753@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         150384
>Category:       bin
>Synopsis:       tr mis-parses '[=]=]' equivalence class
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Sep 08 12:30:00 UTC 2010
>Closed-Date:
>Last-Modified:
>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:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201009081222.o88CMN0j081776>