bug-textutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bug in tr


From: Jim Meyering
Subject: Re: Bug in tr
Date: Sat, 19 Jan 2002 00:38:06 +0100
User-agent: Gnus/5.090004 (Oort Gnus v0.04) Emacs/21.2.50 (i686-pc-linux-gnu)

Pawel Prokop <address@hidden> wrote:
> Hello I've found some problem with tr.
>
> textutils version >=2.0 and <=2.0.18
> linux kernel version 2.2.19, 2.2.20, 2.4.7, 2.4.16
>
> address@hidden:~$ echo pawel prokop rulez | tr [::] _
> tr: tr.c:816: substr: Assertion `first_idx <= last_idx' failed.
> Aborted

Thanks for the report!
I hope to release textutils-2.0.20 pretty soon.

Here's a fix:

        Fix tr so it no longer gets a failed assertion for [::] or [==].

        * src/tr.c (xmemdup): Rename from `substr' and rewrite to
        take only pointer/length parameters.
        (build_spec_list): Update sole caller.
        Properly diagnose the invalid specs [::] and [==].
        Pawel Prokop reported that `tr '[::]' x' elicits a failed assertion.

Index: tr.c
===================================================================
RCS file: /fetish/textutils/src/tr.c,v
retrieving revision 1.107
retrieving revision 1.108
diff -u -p -u -r1.107 -r1.108
--- tr.c        2001/12/03 16:07:50     1.107
+++ tr.c        2002/01/18 19:18:07     1.108
@@ -807,23 +807,16 @@ append_equiv_class (struct Spec_list *li
   return 0;
 }
 
-/* Return a newly allocated copy of the substring P[FIRST_IDX..LAST_IDX].
-   The returned string has length LAST_IDX - FIRST_IDX + 1, may contain
-   NUL bytes, and is *not* NUL-terminated.  */
+/* Return a newly allocated copy of the LEN-byte prefix of P.
+   The returned string may contain NUL bytes and is *not* NUL-terminated.  */
 
 static unsigned char *
-substr (const unsigned char *p, size_t first_idx, size_t last_idx)
+xmemdup (const unsigned char *p, size_t len)
 {
-  size_t len;
-  unsigned char *tmp;
-
-  assert (first_idx <= last_idx);
-  len = last_idx - first_idx + 1;
-  tmp = (unsigned char *) xmalloc (len);
+  unsigned char *tmp = (unsigned char *) xmalloc (len);
 
-  assert (first_idx <= last_idx);
   /* Use memcpy rather than strncpy because `p' may contain zero-bytes.  */
-  memcpy (tmp, p + first_idx, len);
+  memcpy (tmp, p, len);
   return tmp;
 }
 
@@ -995,9 +988,20 @@ build_spec_list (const struct E_string *
              if (found)
                {
                  int parse_failed;
-                 unsigned char *opnd_str = substr (p, i + 2,
-                                                   closing_delim_idx - 1);
                  size_t opnd_str_len = closing_delim_idx - 1 - (i + 2) + 1;
+                 unsigned char *opnd_str;
+
+                 if (opnd_str_len == 0)
+                   {
+                     if (p[i + 1] == ':')
+                       error (0, 0, _("missing character class name `[::]'"));
+                     else
+                       error (0, 0,
+                              _("missing equivalence class character `[==]'"));
+                     return 1;
+                   }
+
+                 opnd_str = xmemdup (p + i + 2, opnd_str_len);
 
                  if (p[i + 1] == ':')
                    {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]