mirror of
https://github.com/Perl/perl5.git
synced 2026-01-26 16:39:36 +00:00
locale: stringify strftime fmt before querying length/utf8ness
POSIX::strftime() can call sv_strftime_common() with arbitrary SVs. SvCUR() assumes it is being called on an actual string. With other SV types it can return garbage or just crash. Make sure SvPV() is called first to stringify the format, before SvUTF8() and SvCUR() inspect the SV. Fixes #22498.
This commit is contained in:
parent
70f3e00650
commit
3e14b2fcf5
@ -9,7 +9,7 @@ use strict;
|
||||
|
||||
use Config;
|
||||
use POSIX;
|
||||
use Test::More tests => 27;
|
||||
use Test::More tests => 31;
|
||||
|
||||
# For the first 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.
|
||||
@ -215,3 +215,14 @@ SKIP: {
|
||||
ok(abs(POSIX::strftime('%s', localtime) - time) < 60,
|
||||
'GH #22351; pr: GH #22369');
|
||||
}
|
||||
|
||||
{
|
||||
# GH #22498
|
||||
is(strftime(42, CORE::localtime), '42', "strftime() works if format is a number");
|
||||
my $obj = bless {}, 'Some::Random::Class';
|
||||
is(strftime($obj, CORE::localtime), "$obj", "strftime() works if format is an object");
|
||||
my $warnings = '';
|
||||
local $SIG{__WARN__} = sub { $warnings .= $_[0] };
|
||||
is(strftime(undef, CORE::localtime), '', "strftime() works if format is undef");
|
||||
like($warnings, qr/^Use of uninitialized value in subroutine entry /, "strftime(undef, ...) produces expected warning");
|
||||
}
|
||||
|
||||
7
locale.c
7
locale.c
@ -8218,6 +8218,9 @@ S_sv_strftime_common(pTHX_ SV * fmt,
|
||||
{ /* Documented above */
|
||||
PERL_ARGS_ASSERT_SV_STRFTIME_COMMON;
|
||||
|
||||
STRLEN fmt_cur;
|
||||
const char *fmt_str = SvPV_const(fmt, fmt_cur);
|
||||
|
||||
utf8ness_t fmt_utf8ness = (SvUTF8(fmt) && LIKELY(! IN_BYTES))
|
||||
? UTF8NESS_YES
|
||||
: UTF8NESS_UNKNOWN;
|
||||
@ -8228,8 +8231,8 @@ S_sv_strftime_common(pTHX_ SV * fmt,
|
||||
* to get almost all the typical returns to fit without the called function
|
||||
* having to realloc; this is a somewhat educated guess, but feel free to
|
||||
* tweak it. */
|
||||
SV* sv = newSV(MAX(SvCUR(fmt) * 2, 64));
|
||||
if (! strftime8(SvPV_nolen(fmt),
|
||||
SV* sv = newSV(MAX(fmt_cur * 2, 64));
|
||||
if (! strftime8(fmt_str,
|
||||
sv,
|
||||
locale,
|
||||
mytm,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user