Re: [perl #24554] Segfault in POSIX module
SADAHIRO Tomoyuki [Sat, 29 Nov 2003 23:32:38 +0000 (08:32 +0900)]
Message-Id: <20031129233010.8E2F.BQW10602@nifty.com>

(plus a test for the stringification of references
passed to POSIX::isXXX())

p4raw-id: //depot/perl@21823

ext/POSIX/POSIX.xs
ext/POSIX/t/is.t
ext/POSIX/t/posix.t

index 6a509b9..049c1b6 100644 (file)
@@ -842,10 +842,12 @@ int_macro_int(sv, iv)
 
 int
 isalnum(charstring)
-       unsigned char * charstring
+       SV *    charstring
+    PREINIT:
+       STRLEN  len;
     CODE:
-       unsigned char *s = charstring;
-       unsigned char *e = SvPOK(ST(0)) ? s + SvCUR(ST(0)) : (unsigned char*)0;
+       unsigned char *s = (unsigned char *) SvPV(charstring, len);
+       unsigned char *e = s + len;
        for (RETVAL = 1; RETVAL && s < e; s++)
            if (!isalnum(*s))
                RETVAL = 0;
@@ -854,10 +856,12 @@ isalnum(charstring)
 
 int
 isalpha(charstring)
-       unsigned char * charstring
+       SV *    charstring
+    PREINIT:
+       STRLEN  len;
     CODE:
-       unsigned char *s = charstring;
-       unsigned char *e = SvPOK(ST(0)) ? s + SvCUR(ST(0)) : (unsigned char*)0;
+       unsigned char *s = (unsigned char *) SvPV(charstring, len);
+       unsigned char *e = s + len;
        for (RETVAL = 1; RETVAL && s < e; s++)
            if (!isalpha(*s))
                RETVAL = 0;
@@ -866,10 +870,12 @@ isalpha(charstring)
 
 int
 iscntrl(charstring)
-       unsigned char * charstring
+       SV *    charstring
+    PREINIT:
+       STRLEN  len;
     CODE:
-       unsigned char *s = charstring;
-       unsigned char *e = SvPOK(ST(0)) ? s + SvCUR(ST(0)) : (unsigned char*)0;
+       unsigned char *s = (unsigned char *) SvPV(charstring, len);
+       unsigned char *e = s + len;
        for (RETVAL = 1; RETVAL && s < e; s++)
            if (!iscntrl(*s))
                RETVAL = 0;
@@ -878,10 +884,12 @@ iscntrl(charstring)
 
 int
 isdigit(charstring)
-       unsigned char * charstring
+       SV *    charstring
+    PREINIT:
+       STRLEN  len;
     CODE:
-       unsigned char *s = charstring;
-       unsigned char *e = SvPOK(ST(0)) ? s + SvCUR(ST(0)) : (unsigned char*)0;
+       unsigned char *s = (unsigned char *) SvPV(charstring, len);
+       unsigned char *e = s + len;
        for (RETVAL = 1; RETVAL && s < e; s++)
            if (!isdigit(*s))
                RETVAL = 0;
@@ -890,10 +898,12 @@ isdigit(charstring)
 
 int
 isgraph(charstring)
-       unsigned char * charstring
+       SV *    charstring
+    PREINIT:
+       STRLEN  len;
     CODE:
-       unsigned char *s = charstring;
-       unsigned char *e = SvPOK(ST(0)) ? s + SvCUR(ST(0)) : (unsigned char*)0;
+       unsigned char *s = (unsigned char *) SvPV(charstring, len);
+       unsigned char *e = s + len;
        for (RETVAL = 1; RETVAL && s < e; s++)
            if (!isgraph(*s))
                RETVAL = 0;
@@ -902,10 +912,12 @@ isgraph(charstring)
 
 int
 islower(charstring)
-       unsigned char * charstring
+       SV *    charstring
+    PREINIT:
+       STRLEN  len;
     CODE:
-       unsigned char *s = charstring;
-       unsigned char *e = SvPOK(ST(0)) ? s + SvCUR(ST(0)) : (unsigned char*)0;
+       unsigned char *s = (unsigned char *) SvPV(charstring, len);
+       unsigned char *e = s + len;
        for (RETVAL = 1; RETVAL && s < e; s++)
            if (!islower(*s))
                RETVAL = 0;
@@ -914,10 +926,12 @@ islower(charstring)
 
 int
 isprint(charstring)
-       unsigned char * charstring
+       SV *    charstring
+    PREINIT:
+       STRLEN  len;
     CODE:
-       unsigned char *s = charstring;
-       unsigned char *e = SvPOK(ST(0)) ? s + SvCUR(ST(0)) : (unsigned char*)0;
+       unsigned char *s = (unsigned char *) SvPV(charstring, len);
+       unsigned char *e = s + len;
        for (RETVAL = 1; RETVAL && s < e; s++)
            if (!isprint(*s))
                RETVAL = 0;
@@ -926,10 +940,12 @@ isprint(charstring)
 
 int
 ispunct(charstring)
-       unsigned char * charstring
+       SV *    charstring
+    PREINIT:
+       STRLEN  len;
     CODE:
-       unsigned char *s = charstring;
-       unsigned char *e = SvPOK(ST(0)) ? s + SvCUR(ST(0)) : (unsigned char*)0;
+       unsigned char *s = (unsigned char *) SvPV(charstring, len);
+       unsigned char *e = s + len;
        for (RETVAL = 1; RETVAL && s < e; s++)
            if (!ispunct(*s))
                RETVAL = 0;
@@ -938,10 +954,12 @@ ispunct(charstring)
 
 int
 isspace(charstring)
-       unsigned char * charstring
+       SV *    charstring
+    PREINIT:
+       STRLEN  len;
     CODE:
-       unsigned char *s = charstring;
-       unsigned char *e = SvPOK(ST(0)) ? s + SvCUR(ST(0)) : (unsigned char*)0;
+       unsigned char *s = (unsigned char *) SvPV(charstring, len);
+       unsigned char *e = s + len;
        for (RETVAL = 1; RETVAL && s < e; s++)
            if (!isspace(*s))
                RETVAL = 0;
@@ -950,10 +968,12 @@ isspace(charstring)
 
 int
 isupper(charstring)
-       unsigned char * charstring
+       SV *    charstring
+    PREINIT:
+       STRLEN  len;
     CODE:
-       unsigned char *s = charstring;
-       unsigned char *e = SvPOK(ST(0)) ? s + SvCUR(ST(0)) : (unsigned char*)0;
+       unsigned char *s = (unsigned char *) SvPV(charstring, len);
+       unsigned char *e = s + len;
        for (RETVAL = 1; RETVAL && s < e; s++)
            if (!isupper(*s))
                RETVAL = 0;
@@ -962,10 +982,12 @@ isupper(charstring)
 
 int
 isxdigit(charstring)
-       unsigned char * charstring
+       SV *    charstring
+    PREINIT:
+       STRLEN  len;
     CODE:
-       unsigned char *s = charstring;
-       unsigned char *e = SvPOK(ST(0)) ? s + SvCUR(ST(0)) : (unsigned char*)0;
+       unsigned char *s = (unsigned char *) SvPV(charstring, len);
+       unsigned char *e = s + len;
        for (RETVAL = 1; RETVAL && s < e; s++)
            if (!isxdigit(*s))
                RETVAL = 0;
index 9ab851c..489b3a9 100644 (file)
@@ -52,6 +52,10 @@ my %classes =
    " \t"       => [ qw(space) ],
 
    "abcde\001" => [],
+
+   # An empty string. Always true (al least in old days) [bug #24554]
+   ''     => [ qw(print graph alnum alpha lower upper digit xdigit
+                  punct cntrl space) ],
   );
 
 
index 912b3d8..58b3a48 100644 (file)
@@ -11,7 +11,7 @@ BEGIN {
 }
 
 require "./test.pl";
-plan(tests => 63);
+plan(tests => 65);
 
 use POSIX qw(fcntl_h signal_h limits_h _exit getcwd open read strftime write
             errno);
@@ -263,6 +263,9 @@ ok(!POSIX::isxdigit('g'), 'isxdigit' );
 # anyway this shouldn't segfault (bug #24554)
 ok( POSIX::isalnum(''),   'isalnum empty string' );
 ok( POSIX::isalnum(undef),'isalnum undef' );
+# those functions should stringify their arguments
+ok(!POSIX::isalpha([]),   'isalpha []' );
+ok( POSIX::isprint([]),   'isprint []' );
  
 # Check that output is not flushed by _exit. This test should be last
 # in the file, and is not counted in the total number of tests.