Skip to content

Commit b1e3ba2

Browse files
haargleonerd
authored andcommitted
always prevent setting POK flag when NV values are used as strings
Since PR #18958, values that start as IVs will not get their POK flags set when they are used as strings. This is meant to aid in serialization, allowing the "original" type of a value to be preserved. For NV values, the POK flag was already usually not being set, because the string form of a float could change based on the locale changing. However, for Inf and NaN values, the POK flag would still be enabled. Also, POK would be set for all floats if USE_LOCALE_NUMERIC was not defined. Update Perl_sv_2pv_flags to only enable the POKp flag when storing the PV for Inf or NaN values, or all NVs when USE_LOCALE_NUMERIC is not defined.
1 parent fa5eb2f commit b1e3ba2

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

sv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3005,7 +3005,7 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const U32 flags)
30053005
len = S_infnan_2pv(SvNVX(sv), s, size, 0);
30063006
if (len > 0) {
30073007
s += len;
3008-
SvPOK_on(sv);
3008+
SvPOKp_on(sv);
30093009
}
30103010
else {
30113011
/* some Xenix systems wipe out errno here */
@@ -3025,7 +3025,7 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const U32 flags)
30253025
#ifndef USE_LOCALE_NUMERIC
30263026
SNPRINTF_G(SvNVX(sv), s, SvLEN(sv), NV_DIG);
30273027

3028-
SvPOK_on(sv);
3028+
SvPOKp_on(sv);
30293029
#else
30303030
{
30313031
bool local_radix;

t/op/svflags.t

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ BEGIN {
1010
# Tests the new documented mechanism for determining the original type
1111
# of an SV.
1212

13-
plan tests => 4;
13+
plan tests => 12;
1414
use strict;
1515
use B qw(svref_2object SVf_IOK SVf_NOK SVf_POK);
1616

@@ -22,6 +22,41 @@ my $y = $x . "";
2222

2323
is($xobj->FLAGS & (SVf_IOK | SVf_POK), SVf_IOK, "POK not set on IV used as string");
2424

25+
$x = 1.0;
26+
27+
is($xobj->FLAGS & (SVf_NOK | SVf_POK), SVf_NOK, "correct base flags on NV");
28+
29+
$y = $x . "";
30+
31+
is($xobj->FLAGS & (SVf_NOK | SVf_POK), SVf_NOK, "POK not set on NV used as string");
32+
33+
$x = "Inf" + 0;
34+
35+
is($xobj->FLAGS & (SVf_NOK | SVf_POK), SVf_NOK, "correct base flags on Inf NV");
36+
37+
$y = $x . "";
38+
39+
is($xobj->FLAGS & (SVf_NOK | SVf_POK), SVf_NOK, "POK not set on Inf NV used as string");
40+
41+
$x = "-Inf" + 0;
42+
43+
is($xobj->FLAGS & (SVf_NOK | SVf_POK), SVf_NOK, "correct base flags on -Inf NV");
44+
45+
$y = $x . "";
46+
47+
is($xobj->FLAGS & (SVf_NOK | SVf_POK), SVf_NOK, "POK not set on -Inf NV used as string");
48+
49+
{
50+
local $^W = 0;
51+
$x = "NaN" + 0;
52+
}
53+
54+
is($xobj->FLAGS & (SVf_NOK | SVf_POK), SVf_NOK, "correct base flags on NaN NV");
55+
56+
$y = $x . "";
57+
58+
is($xobj->FLAGS & (SVf_NOK | SVf_POK), SVf_NOK, "POK not set on NaN NV used as string");
59+
2560
$x = "10";
2661
is($xobj->FLAGS & (SVf_IOK | SVf_POK), SVf_POK, "correct base flags on PV");
2762

0 commit comments

Comments
 (0)