bug-gnu-utils
[Top][All Lists]
Advanced

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

Re: gawk substr() problem


From: Paul Eggert
Subject: Re: gawk substr() problem
Date: Wed, 20 Nov 2002 05:44:54 -0800 (PST)

> Date: Tue, 19 Nov 2002 15:37:54 +0200
> From: Aharon Robbins <address@hidden>
> 
> See patch below that fixes this.

Unfortunately that patch isn't complete or portable, e.g., it assumes
that size_t is the same width as unsigned long.  Also, the current
code assumes that when you assign an out-of-range floating point value
(or a NaN) to an integer, you silently get the maximal integer, but
this assumption isn't portable either.

How about the following patch instead?

2002-11-20  Paul Eggert  <address@hidden>

        * builtin.c (do_substr): Consistently use floating point
        values for lint messages, so they should be printed pretty
        much as the user saw them.  Check for overflow before
        converting floating point to integer.  Do the right thing with
        NaNs.  Allow zero-length substrings when checking for lint.
        Check for index out-of-range before checking for length
        out-of-range, to avoid some nasty effects if address
        arithmetic overflows (e.g., indx + length < index).

--- builtin.c   2002/08/10 10:12:26     3.1.1.2
+++ builtin.c   2002/11/20 13:34:28     3.1.1.4
@@ -1187,7 +1187,11 @@ do_substr(NODE *tree)
                lintwarn(_("substr: non-integer start index %g will be 
truncated"),
                         d_index);
 
-       indx = d_index - 1;     /* awk indices are from 1, C's are from 0 */
+       /* awk indices are from 1, C's are from 0 */
+       if (d_index <= (size_t) -1)
+               indx = d_index - 1;
+       else
+               indx = (size_t) -1;
 
        if (tree->rnode->rnode == NULL) {       /* third arg. missing */
                /* use remainder of string */
@@ -1196,9 +1200,9 @@ do_substr(NODE *tree)
                t3 = tree_eval(tree->rnode->rnode->lnode);
                d_length = force_number(t3);
                free_temp(t3);
-               if (d_length <= 0.0) {
+               if (d_length < 0.0) {
                        if (do_lint)
-                               lintwarn(_("substr: length %g is <= 0"), 
d_length);
+                               lintwarn(_("substr: length %g is < 0"), 
d_length);
                        free_temp(t1);
                        return Nnull_string;
                }
@@ -1206,29 +1210,32 @@ do_substr(NODE *tree)
                        lintwarn(
                _("substr: non-integer length %g will be truncated"),
                                d_length);
-               length = d_length;
+               if (d_length < (size_t) -1)
+                       length = d_length;
+               else
+                       length = (size_t) -1;
        }
 
        if (t1->stlen == 0) {
-               if (do_lint)
+               if (do_lint && (indx | length) != 0)
                        lintwarn(_("substr: source string is zero length"));
                free_temp(t1);
                return Nnull_string;
        }
-       if ((indx + length) > t1->stlen) {
-               if (do_lint)
-                       lintwarn(
-       _("substr: length %d at start index %d exceeds length of first argument 
(%d)"),
-                       length, indx+1, t1->stlen);
-               length = t1->stlen - indx;
-       }
        if (indx >= t1->stlen) {
-               if (do_lint)
-                       lintwarn(_("substr: start index %d is past end of 
string"),
-                               indx+1);
+               if (do_lint && indx > t1->stlen)
+                       lintwarn(_("substr: start index %g is past end of 
string"),
+                               d_index);
                free_temp(t1);
                return Nnull_string;
        }
+       if (length > t1->stlen - indx) {
+               if (do_lint)
+                       lintwarn(
+       _("substr: length %g at start index %g exceeds length of first argument 
(%lu)"),
+               d_length, d_index, (unsigned long int) t1->stlen);
+               length = t1->stlen - indx;
+       }
        r = tmp_string(t1->stptr + indx, length);
        free_temp(t1);
        return r;




reply via email to

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