Author: julianalbo
Date: Sat Aug  9 10:09:00 2008
New Revision: 30143

Modified:
   trunk/include/parrot/string_funcs.h
   trunk/src/string.c

Log:
throws on invalid null argument to string_substr

Modified: trunk/include/parrot/string_funcs.h
==============================================================================
--- trunk/include/parrot/string_funcs.h (original)
+++ trunk/include/parrot/string_funcs.h Sat Aug  9 10:09:00 2008
@@ -445,13 +445,12 @@
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 STRING * string_substr(PARROT_INTERP,
-    ARGIN(STRING *src),
+    ARGIN_NULLOK(STRING *src),
     INTVAL offset,
     INTVAL length,
     ARGOUT_NULLOK(STRING **d),
     int replace_dest)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(1);
 
 PARROT_API
 PARROT_CANNOT_RETURN_NULL

Modified: trunk/src/string.c
==============================================================================
--- trunk/src/string.c  (original)
+++ trunk/src/string.c  Sat Aug  9 10:09:00 2008
@@ -1083,53 +1083,59 @@
 PARROT_CANNOT_RETURN_NULL
 PARROT_WARN_UNUSED_RESULT
 STRING *
-string_substr(PARROT_INTERP, ARGIN(STRING *src), INTVAL offset, INTVAL length,
+string_substr(PARROT_INTERP,
+        ARGIN_NULLOK(STRING *src), INTVAL offset, INTVAL length,
         ARGOUT_NULLOK(STRING **d), int replace_dest)
 {
-    STRING *dest;
-    UINTVAL true_length;
-    UINTVAL true_offset = (UINTVAL)offset;
+    if (src == NULL)
+        Parrot_ex_throw_from_c_args(interp, NULL, 
EXCEPTION_SUBSTR_OUT_OF_STRING,
+            "Cannot substr on a null string");
+    else {
+        STRING *dest;
+        UINTVAL true_length;
+        UINTVAL true_offset = (UINTVAL)offset;
 
-    saneify_string(src);
+        saneify_string(src);
 
-    /* Allow regexes to return $' easily for "aaa" =~ /aaa/ */
-    if (offset == (INTVAL)string_length(interp, src) || length < 1)
-        return string_make_empty(interp, enum_stringrep_one, 0);
+        /* Allow regexes to return $' easily for "aaa" =~ /aaa/ */
+        if (offset == (INTVAL)string_length(interp, src) || length < 1)
+            return string_make_empty(interp, enum_stringrep_one, 0);
 
-    if (offset < 0)
-        true_offset = (UINTVAL)(src->strlen + offset);
+        if (offset < 0)
+            true_offset = (UINTVAL)(src->strlen + offset);
 
-    /* 0 based... */
-    if (src->strlen == 0 || true_offset > src->strlen - 1)
-        Parrot_ex_throw_from_c_args(interp, NULL, 
EXCEPTION_SUBSTR_OUT_OF_STRING,
-            "Cannot take substr outside string");
+        /* 0 based... */
+        if (src->strlen == 0 || true_offset > src->strlen - 1)
+            Parrot_ex_throw_from_c_args(interp, NULL, 
EXCEPTION_SUBSTR_OUT_OF_STRING,
+                "Cannot take substr outside string");
 
-    true_length = (UINTVAL)length;
-    if (true_length > (src->strlen - true_offset))
-        true_length = (UINTVAL)(src->strlen - true_offset);
+        true_length = (UINTVAL)length;
+        if (true_length > (src->strlen - true_offset))
+            true_length = (UINTVAL)(src->strlen - true_offset);
 
-    /* do in-place i.e. reuse existing header if one */
-    if (replace_dest && d && *d) {
-        PARROT_ASSERT(src->encoding == Parrot_fixed_8_encoding_ptr);
-        dest           = *d;
+        /* do in-place i.e. reuse existing header if one */
+        if (replace_dest && d && *d) {
+            PARROT_ASSERT(src->encoding == Parrot_fixed_8_encoding_ptr);
+            dest           = *d;
 
-        dest->encoding = src->encoding;
-        dest->charset  = src->charset;
+            dest->encoding = src->encoding;
+            dest->charset  = src->charset;
 
-        dest->strstart = (char *)src->strstart + true_offset;
-        dest->bufused  = true_length;
+            dest->strstart = (char *)src->strstart + true_offset;
+            dest->bufused  = true_length;
 
-        dest->strlen   = true_length;
-        dest->hashval  = 0;
-    }
-    else
-        dest = CHARSET_GET_CODEPOINTS(interp, src, true_offset,
-                true_length);
+            dest->strlen   = true_length;
+            dest->hashval  = 0;
+        }
+        else
+            dest = CHARSET_GET_CODEPOINTS(interp, src, true_offset,
+                    true_length);
 
-    if (d)
-        *d = dest;
+        if (d)
+            *d = dest;
 
-    return dest;
+        return dest;
+    }
 }
 
 

Reply via email to