From: Paul "LeoNerd" Evans Date: Wed, 1 Feb 2012 19:37:34 +0000 (+0000) Subject: When strptime() receives a reference, ensure it's a mutable scalar X-Git-Tag: accepted/trunk/20130322.191538~703^2~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cb6fe7a068e66c90514327b21407ae06469ce598;p=platform%2Fupstream%2Fperl.git When strptime() receives a reference, ensure it's a mutable scalar --- diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs index 64fe3fb..2250f03 100644 --- a/ext/POSIX/POSIX.xs +++ b/ext/POSIX/POSIX.xs @@ -1876,9 +1876,12 @@ strptime(str, fmt, sec=-1, min=-1, hour=-1, mday=-1, mon=-1, year=-1, wday=-1, y tm.tm_yday = yday; tm.tm_isdst = isdst; - if(SvROK(str)) { + if(SvROK(str) && !SvOBJECT(SvRV(str))) { strref = SvRV(str); + if(SvTYPE(strref) > SVt_PVMG || SvREADONLY(strref)) + croak("str is not a reference to a mutable scalar"); + str_base = str_c = SvPV_nolen(strref); if(SvTYPE(strref) >= SVt_PVMG && SvMAGIC(strref)) @@ -1887,6 +1890,9 @@ strptime(str, fmt, sec=-1, min=-1, hour=-1, mday=-1, mon=-1, year=-1, wday=-1, y if(posmg) str_c += posmg->mg_len; } + else if(SvROK(str) && SvTYPE(SvRV(str)) == SVt_REGEXP) { + croak("str is not a reference to a mutable scalar"); + } else { str_c = SvPV_nolen(str); } diff --git a/ext/POSIX/t/time.t b/ext/POSIX/t/time.t index bbf2c50..959f675 100644 --- a/ext/POSIX/t/time.t +++ b/ext/POSIX/t/time.t @@ -4,7 +4,7 @@ use strict; use Config; use POSIX; -use Test::More tests => 29; +use Test::More tests => 33; # go to UTC to avoid DST issues around the world when testing. SUS3 says that # null should get you UTC, but some environments want the explicit names. @@ -98,6 +98,24 @@ pos($str) = 10; is_deeply(\@time, [0, 0, 0, 1, 12-1, 2012-1900, 6, 335, 0], 'strptime() starts SCALAR ref at pos()'); is(pos($str), 20, 'strptime() updates pos() magic on SCALAR ref'); +eval { POSIX::strptime({}, "format") }; +like($@, qr/not a reference to a mutable scalar/, 'strptime() dies on HASH ref'); + +eval { POSIX::strptime(\"boo", "format") }; +like($@, qr/not a reference to a mutable scalar/, 'strptime() dies on const literal ref'); + +eval { POSIX::strptime(qr/boo!/, "format") }; +like($@, qr/not a reference to a mutable scalar/, 'strptime() dies on Regexp'); + +$str = bless [], "WithStringOverload"; +{ + package WithStringOverload; + use overload '""' => sub { return "2012-02-01" }; +} + +@time = POSIX::strptime($str, "%Y-%m-%d", 0, 0, 0); +is_deeply(\@time, [0, 0, 0, 1, 2-1, 2012-1900, 3, 31, 0], 'strptime() allows object with string overload'); + setlocale(LC_TIME, $orig_loc) || die "Cannot setlocale() back to orig: $!"; # clock() seems to have different definitions of what it does between POSIX