From 59b61096be97d8d463125e3b0422c5a6bd05f1e5 Mon Sep 17 00:00:00 2001 From: Anatoly Vorobey Date: Sun, 8 Oct 2006 10:58:16 -0700 Subject: [PATCH] [perl #40473] sprintf width+precision fails on wide chars From: Anatoly Vorobey (via RT) Message-ID: p4raw-id: //depot/perl@28985 --- sv.c | 6 +++++- t/op/sprintf2.t | 11 ++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/sv.c b/sv.c index 4fa4498..7dd83cc 100644 --- a/sv.c +++ b/sv.c @@ -8919,13 +8919,17 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV else { eptr = SvPVx_const(argsv, elen); if (DO_UTF8(argsv)) { + I32 old_precis = precis; if (has_precis && precis < elen) { I32 p = precis; sv_pos_u2b(argsv, &p, 0); /* sticks at end */ precis = p; } if (width) { /* fudge width (can't fudge elen) */ - width += elen - sv_len_utf8(argsv); + if (has_precis && precis < elen) + width += precis - old_precis; + else + width += elen - sv_len_utf8(argsv); } is_utf8 = TRUE; } diff --git a/t/op/sprintf2.t b/t/op/sprintf2.t index 81450ce..90214ab 100644 --- a/t/op/sprintf2.t +++ b/t/op/sprintf2.t @@ -6,7 +6,7 @@ BEGIN { require './test.pl'; } -plan tests => 280; +plan tests => 284; is( sprintf("%.40g ",0.01), @@ -28,6 +28,15 @@ for my $i (1, 5, 10, 20, 50, 100) { "width calculation under utf8 upgrade, length=$i"); } +# check simultaneous width & precision with wide characters +for my $i (1, 3, 5, 10) { + my $string = "\x{0410}"x($i+10); # cyrillic capital A + my $expect = "\x{0410}"x$i; # cut down to exactly $i characters + my $format = "%$i.${i}s"; + is(sprintf($format, $string), $expect, + "width & precision interplay with utf8 strings, length=$i"); +} + # Used to mangle PL_sv_undef fresh_perl_is( 'print sprintf "xxx%n\n"; print undef', -- 2.7.4