Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.

Commit df3cb29

Browse files
committed
Cpanel-JSON-XS: Update to 3.0236
Stringify true again as "1" Disallow duplicate keys by default, only allow them in relaxed mode. De-fragilize t/96_mojo.t false test to "". It mostly is. Fix and unify utf8 handling with 5.6.2 and improve many utf8 tests. Add tests for boolean sv_yes and sv_no Check for correct module in %INC (Patrick Cronin #89) Fix inf/nan for strawberry 5.26
1 parent 1953da4 commit df3cb29

File tree

14 files changed

+281
-187
lines changed

14 files changed

+281
-187
lines changed

MANIFEST

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ cpan/Cpanel-JSON-XS/t/22_comment_at_eof.t
415415
cpan/Cpanel-JSON-XS/t/23_array_ctx.t
416416
cpan/Cpanel-JSON-XS/t/24_freeze_recursion.t
417417
cpan/Cpanel-JSON-XS/t/25_boolean.t
418+
cpan/Cpanel-JSON-XS/t/26_duplicate.t
418419
cpan/Cpanel-JSON-XS/t/31_bom.t
419420
cpan/Cpanel-JSON-XS/t/52_object.t
420421
cpan/Cpanel-JSON-XS/t/53_readonly.t

META.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,5 +142,5 @@
142142
}
143143
},
144144
"version" : "5.027001c",
145-
"x_serialization_backend" : "Cpanel::JSON::XS version 3.0233"
145+
"x_serialization_backend" : "Cpanel::JSON::XS version 3.0236"
146146
}

Porting/Maintainers.pl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ package Maintainers;
437437
},
438438

439439
'Cpanel::JSON::XS' => {
440-
'DISTRIBUTION' => 'RURBAN/Cpanel-JSON-XS-3.0233.tar.gz',
440+
'DISTRIBUTION' => 'RURBAN/Cpanel-JSON-XS-3.0236.tar.gz',
441441
'FILES' => q[cpan/Cpanel-JSON-XS],
442442
'EXCLUDED' => [
443443
'.appveyor.yml',

cpan/Cpanel-JSON-XS/XS.pm

Lines changed: 137 additions & 118 deletions
Large diffs are not rendered by default.

cpan/Cpanel-JSON-XS/XS.xs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@
3737
#define UTF32BOM_BE "\000\000\376\377" /* 00 00 FE FF */
3838

3939
/* strawberry 5.22 with USE_MINGW_ANSI_STDIO and USE_LONG_DOUBLE has now
40-
a proper inf/nan */
40+
a proper inf/nan. */
4141
#if defined(WIN32) && !defined(__USE_MINGW_ANSI_STDIO) && !defined(USE_LONG_DOUBLE)
42-
# if _MSC_VER > 1800
42+
/* TODO: we really need the msvcrt version, not the MSVC version.
43+
strawberry 5.26 uses it also now. */
44+
# if (_MSC_VER > 1800) || (!defined(_MSC_VER) && PERL_VERSION >= 26)
4345
# define STR_INF "inf"
4446
# define STR_INF2 "inf.0"
4547
# define STR_NAN "nan"
@@ -235,11 +237,7 @@ mingw_modfl(long double x, long double *ip)
235237

236238
#define SHORT_STRING_LEN 16384 // special-case strings of up to this size
237239

238-
#if PERL_VERSION >= 8
239240
#define DECODE_WANTS_OCTETS(json) ((json)->flags & F_UTF8)
240-
#else
241-
#define DECODE_WANTS_OCTETS(json) (0)
242-
#endif
243241

244242
#define SB do {
245243
#define SE } while (0)
@@ -2705,6 +2703,7 @@ decode_hv (pTHX_ dec_t *dec)
27052703
HV *hv = newHV ();
27062704
int allow_squote = dec->json.flags & F_ALLOW_SQUOTE;
27072705
int allow_barekey = dec->json.flags & F_ALLOW_BAREKEY;
2706+
int relaxed = dec->json.flags & F_RELAXED;
27082707
char endstr = '"';
27092708

27102709
DEC_INC_DEPTH;
@@ -2786,6 +2785,10 @@ decode_hv (pTHX_ dec_t *dec)
27862785
if (UNLIKELY(p - key > I32_MAX))
27872786
ERR ("Hash key too large");
27882787
#endif
2788+
if (!relaxed && UNLIKELY(hv_exists (hv, key, len))) {
2789+
ERR ("Duplicate keys not allowed");
2790+
}
2791+
27892792
dec->cur = p + 1;
27902793

27912794
decode_ws (dec); if (*p != ':') EXPECT_CH (':');
@@ -2847,7 +2850,7 @@ decode_hv (pTHX_ dec_t *dec)
28472850

28482851
/* the next line creates a mortal sv each time it's called. */
28492852
/* might want to optimise this for common cases. */
2850-
if (LIKELY(he))
2853+
if (LIKELY((long)he))
28512854
cb = hv_fetch_ent (dec->json.cb_sk_object, hv_iterkeysv (he), 0, 0);
28522855

28532856
if (cb)
@@ -3185,14 +3188,12 @@ decode_json (pTHX_ SV *string, JSON *json, STRLEN *offset_return)
31853188
}
31863189
}
31873190

3188-
#if PERL_VERSION >= 8
31893191
if (LIKELY(!converted)) {
31903192
if (DECODE_WANTS_OCTETS (json))
31913193
sv_utf8_downgrade (string, 0);
31923194
else
31933195
sv_utf8_upgrade (string);
31943196
}
3195-
#endif
31963197

31973198
/* should basically be a NOP but needed for 5.6 with undef */
31983199
if (!SvPOK(string))

cpan/Cpanel-JSON-XS/t/01_utf8.t

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,76 @@
1-
use Test::More tests => 155;
1+
use Test::More tests => 162;
22
use utf8;
33
use Cpanel::JSON::XS;
4+
use warnings;
45

5-
is(Cpanel::JSON::XS->new->allow_nonref (1)->utf8 (1)->encode ("ü"), "\"\xc3\xbc\"");
6-
is(Cpanel::JSON::XS->new->allow_nonref (1)->encode ("ü"), "\"ü\"");
6+
is(Cpanel::JSON::XS->new->allow_nonref->utf8->encode("ü"), "\"\xc3\xbc\"");
7+
is(Cpanel::JSON::XS->new->allow_nonref->encode("ü"), "\"ü\"");
78

8-
is(Cpanel::JSON::XS->new->allow_nonref (1)->ascii (1)->utf8 (1)->encode (chr 0x8000), '"\u8000"');
9-
is(Cpanel::JSON::XS->new->allow_nonref (1)->ascii (1)->utf8 (1)->pretty (1)->encode (chr 0x10402), "\"\\ud801\\udc02\"\n");
9+
is(Cpanel::JSON::XS->new->allow_nonref->ascii->utf8->encode(chr 0x8000), '"\u8000"');
10+
is(Cpanel::JSON::XS->new->allow_nonref->ascii->utf8->pretty->encode(chr 0x10402), "\"\\ud801\\udc02\"\n");
11+
12+
ok not defined eval { Cpanel::JSON::XS->new->allow_nonref->utf8->decode('"ü"') };
13+
like $@, qr/malformed UTF-8/;
14+
15+
is(Cpanel::JSON::XS->new->allow_nonref->decode('"ü"'), "ü");
16+
is(Cpanel::JSON::XS->new->allow_nonref->decode('"\u00fc"'), "ü");
17+
18+
ok not defined eval { decode_json ('"\ud801\udc02' . "\x{10204}\"", 1) };
19+
like $@, qr/Wide character/;
1020

1121
SKIP: {
1222
skip "5.6", 1 if $] < 5.008;
13-
eval { Cpanel::JSON::XS->new->allow_nonref (1)->utf8 (1)->decode ('"ü"') };
14-
like $@, qr/malformed UTF-8/;
23+
is(Cpanel::JSON::XS->new->allow_nonref->decode('"\ud801\udc02' . "\x{10204}\""), "\x{10402}\x{10204}");
1524
}
1625

17-
is(Cpanel::JSON::XS->new->allow_nonref (1)->decode ('"ü"'), "ü");
18-
is(Cpanel::JSON::XS->new->allow_nonref (1)->decode ('"\u00fc"'), "ü");
19-
if ($] < 5.008) {
20-
eval { decode_json ('"\ud801\udc02' . "\x{10204}\"", 1) };
21-
like $@, qr/malformed UTF-8/;
22-
} else {
23-
is(Cpanel::JSON::XS->new->allow_nonref (1)->decode ('"\ud801\udc02' . "\x{10204}\""), "\x{10402}\x{10204}");
24-
}
25-
is(Cpanel::JSON::XS->new->allow_nonref (1)->decode ('"\"\n\\\\\r\t\f\b"'), "\"\012\\\015\011\014\010");
26+
is(Cpanel::JSON::XS->new->allow_nonref->decode('"\"\n\\\\\r\t\f\b"'), "\"\012\\\015\011\014\010");
2627

27-
my $love = $] < 5.008 ? "I \342\235\244 perl" : "I ❤ perl";
28-
is(Cpanel::JSON::XS->new->ascii->encode ([$love]),
29-
$] < 5.008 ? '["I \u00e2\u009d\u00a4 perl"]' : '["I \u2764 perl"]', 'utf8 enc ascii');
30-
is(Cpanel::JSON::XS->new->latin1->encode ([$love]),
31-
$] < 5.008 ? "[\"I \342\235\244 perl\"]" : '["I \u2764 perl"]', 'utf8 enc latin1');
28+
my $utf8_love = "I \342\235\244 perl";
29+
is(Cpanel::JSON::XS->new->ascii->encode([$utf8_love]), '["I \u00e2\u009d\u00a4 perl"]', 'utf8 enc ascii');
30+
is(Cpanel::JSON::XS->new->latin1->encode([$utf8_love]), "[\"I \342\235\244 perl\"]", 'utf8 enc latin1');
31+
is(Cpanel::JSON::XS->new->utf8->encode([$utf8_love]), "[\"I \303\242\302\235\302\244 perl\"]", 'utf8 enc utf8');
32+
is(Cpanel::JSON::XS->new->binary->encode([$utf8_love]), '["I \xe2\x9d\xa4 perl"]', 'utf8 enc binary');
3233

3334
SKIP: {
34-
skip "5.6", 1 if $] < 5.008;
35-
require Encode;
36-
# [RT #84244] wrong complaint: JSON::XS double encodes to ["I ❤ perl"]
37-
# and with utf8 triple encodes it to ["I ❤ perl"]
38-
if ($Encode::VERSION < 2.40 or $Encode::VERSION >= 2.54) { # Encode stricter check: Cannot decode string with wide characters
39-
# see also http://stackoverflow.com/questions/12994100/perl-encode-pm-cannot-decode-string-with-wide-character
40-
$love = "I \342\235\244 perl";
41-
}
42-
my $s = Encode::decode_utf8($love); # User tries to double decode wide-char to unicode with Encode
43-
is(Cpanel::JSON::XS->new->utf8->encode ([$s]), "[\"I \342\235\244 perl\"]", 'utf8 enc utf8 [RT #84244]');
35+
skip "5.6", 4 if $] < 5.008;
36+
my $unicode_love = "I ❤ perl";
37+
is(Cpanel::JSON::XS->new->ascii->encode([$unicode_love]), '["I \u2764 perl"]', 'unicode enc ascii');
38+
is(Cpanel::JSON::XS->new->latin1->encode([$unicode_love]), "[\"I \\u2764 perl\"]", 'unicode enc latin1');
39+
is(Cpanel::JSON::XS->new->utf8->encode([$unicode_love]), "[\"I \342\235\244 perl\"]", 'unicode enc utf8');
40+
is(Cpanel::JSON::XS->new->binary->encode([$unicode_love]), '["I \xe2\x9d\xa4 perl"]', 'unicode enc binary');
4441
}
45-
is(Cpanel::JSON::XS->new->binary->encode ([$love]), '["I \xe2\x9d\xa4 perl"]', 'utf8 enc binary');
4642

4743
# TODO: test utf8 hash keys,
4844
# test utf8 strings without any char > 0x80.
4945

5046
# warn on the 66 non-characters as in core
5147
{
52-
my $w;
53-
require warnings;
54-
warnings->unimport($] < 5.014 ? 'utf8' : 'nonchar');
48+
BEGIN { 'warnings'->import($] < 5.014 ? 'utf8' : 'nonchar') }
49+
my $w = '';
5550
$SIG{__WARN__} = sub { $w = shift };
5651
my $d = Cpanel::JSON::XS->new->allow_nonref->decode('"\ufdd0"');
5752
my $warn = $w;
58-
is ($d, "\x{fdd0}", substr($warn,0,31)."...");
53+
{
54+
no warnings 'utf8';
55+
is ($d, "\x{fdd0}", substr($warn,0,31)."...");
56+
}
5957
like ($warn, qr/^Unicode non-character U\+FDD0 is/);
6058
$w = '';
6159
# higher planes
6260
$d = Cpanel::JSON::XS->new->allow_nonref->decode('"\ud83f\udfff"');
6361
$warn = $w;
64-
is ($d, "\x{1ffff}", substr($warn,0,31)."...");
62+
{
63+
no warnings 'utf8';
64+
is ($d, "\x{1ffff}", substr($warn,0,31)."...");
65+
}
6566
like ($w, qr/^Unicode non-character U\+1FFFF is/);
6667
$w = '';
6768
$d = Cpanel::JSON::XS->new->allow_nonref->decode('"\ud87f\udffe"');
6869
$warn = $w;
69-
is ($d, "\x{2fffe}", substr($warn,0,31)."...");
70+
{
71+
no warnings 'utf8';
72+
is ($d, "\x{2fffe}", substr($warn,0,31)."...");
73+
}
7074
like ($w, qr/^Unicode non-character U\+2FFFE is/);
7175

7276
$w = '';
@@ -77,12 +81,15 @@ is(Cpanel::JSON::XS->new->binary->encode ([$love]), '["I \xe2\x9d\xa4 perl"]', '
7781
}
7882
{
7983
my $w;
80-
warnings->unimport($] < 5.014 ? 'utf8' : 'nonchar');
84+
BEGIN { 'warnings'->import($] < 5.014 ? 'utf8' : 'nonchar') }
8185
$SIG{__WARN__} = sub { $w = shift };
8286
# no warning with relaxed
8387
my $d = Cpanel::JSON::XS->new->allow_nonref->relaxed->decode('"\ufdd0"');
8488
my $warn = $w;
85-
is ($d, "\x{fdd0}", "no warning with relaxed");
89+
{
90+
no warnings 'utf8';
91+
is ($d, "\x{fdd0}", "no warning with relaxed");
92+
}
8693
is($w, undef);
8794
}
8895

@@ -144,9 +151,9 @@ my @ill =
144151
{
145152
# these are no multibyte codepoints, just raw utf8 bytes,
146153
# so most of them work with 5.6 also.
147-
$^W = 1;
154+
BEGIN { $^W = 1 }
155+
BEGIN { 'warnings'->import($] < 5.014 ? 'utf8' : 'nonchar') }
148156
my $w;
149-
warnings->import($] < 5.014 ? 'utf8' : 'nonchar');
150157
$SIG{__WARN__} = sub { $w = shift };
151158

152159
for my $ill (@ill) {

cpan/Cpanel-JSON-XS/t/03_types.t

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ ok ($true eq "true", "true: eq $true");
2222
ok ("$false" eq "0", "false: stringified $false eq 0");
2323
#ok ("$false" eq "false", "false: stringified $false eq false");
2424
#ok ("$true" eq "1", "true: stringified $true eq 1");
25-
ok ("$true" eq "true", "true: stringified $true");
25+
ok ("$true" eq "1", "true: stringified $true");
2626
{
2727
my $FH;
2828
my $fn = "tmp_$$";
@@ -32,7 +32,7 @@ ok ("$true" eq "true", "true: stringified $true");
3232
open $FH, "<", $fn;
3333
my $s = <$FH>;
3434
close $FH;
35-
ok ($s eq "0true\n", $s); # 11
35+
ok ($s eq "01\n", $s); # 11
3636
unlink $fn;
3737
}
3838

cpan/Cpanel-JSON-XS/t/117_numbers.t

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ if ($^O eq 'MSWin32'
3737
$have_qnan = 0;
3838
($inf, $neg_inf, $nan, $neg_nan) = ('inf','-inf','nan','-nan');
3939
}
40+
if ($^O eq 'MSWin32'
41+
and $Config{cc} eq 'gcc'
42+
and $] >= 5.026) # updated strawberry
43+
{
44+
$have_qnan = 0;
45+
($inf, $neg_inf, $nan, $neg_nan) = ('inf','-inf','nan','-nan');
46+
}
4047
# Windows changed it with MSVC 14.0 and the ucrtd.dll runtime
4148
diag "ccversion = $Config{ccversion}" if $^O eq 'MSWin32' and $Config{ccversion};
4249
if ($^O eq 'MSWin32' and $Config{ccversion}) {

cpan/Cpanel-JSON-XS/t/25_boolean.t

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
use strict;
2-
use Test::More tests => 17;
2+
use Test::More tests => 32;
33
use Cpanel::JSON::XS ();
44

55
my $booltrue = q({"is_true":true});
66
my $boolfalse = q({"is_false":false});
7-
# since 5.16 yes/no is !0/!1, but for earlier perls we need to use a BoolSV
8-
my $a = 0;
9-
my $yes = do{$a==0}; # < 5.16 !0 is not sv_yes
10-
my $no = do{$a==1}; # < 5.16 !1 is not sv_no
11-
my $yesno = [ $yes, $no ]; # native yes/no. YAML::XS compatible
127
my $truefalse = "[true,false]";
138
my $cjson = Cpanel::JSON::XS->new;
149
my $true = Cpanel::JSON::XS::true;
1510
my $false = Cpanel::JSON::XS::false;
1611

12+
my $nonref_cjson = Cpanel::JSON::XS->new->allow_nonref;
13+
1714
# from JSON::MaybeXS
1815
my $data = $cjson->decode('{"foo": true, "bar": false, "baz": 1}');
1916
ok($cjson->is_bool($data->{foo}), 'true decodes to a bool')
@@ -37,10 +34,43 @@ is( $cjson->encode( [\1,\0] ), $truefalse );
3734
is( $cjson->encode( [ $true, $false] ),
3835
$truefalse );
3936

40-
TODO: {
41-
local $TODO = 'GH #39';
42-
is( $cjson->encode( $yesno ), $truefalse, "map yes/no to [true,false]");
37+
# GH #39
38+
# perl block which returns sv_no or sv_yes
39+
is( $nonref_cjson->encode( do{(my $a=0)==1} ), "false", "map do{(my \$a)=0)==1} to false");
40+
is( $nonref_cjson->encode( do{(my $a=0)==1} ), "false", "map do{(my \$a)=0)==1} to false");
41+
is( $nonref_cjson->encode( do{(my $a=1)==1} ), "true", "map do{(my \$a)=1)==1} to true");
42+
is( $nonref_cjson->encode( do{(my $a=1)==1} ), "true", "map do{(my \$a)=1)==1} to true");
43+
44+
# GH #39
45+
# XS function UNIVERSAL::isa returns sv_no or sv_yes
46+
is( $nonref_cjson->encode( UNIVERSAL::isa('0', '1') ), "false", "map UNIVERSAL::isa('0', '1') to false");
47+
is( $nonref_cjson->encode( UNIVERSAL::isa('0', '1') ), "false", "map UNIVERSAL::isa('0', '1') to false");
48+
is( $nonref_cjson->encode( UNIVERSAL::isa('UNIVERSAL', 'UNIVERSAL') ), "true", "map UNIVERSAL::isa('UNIVERSAL', 'UNIVERSAL') to true");
49+
is( $nonref_cjson->encode( UNIVERSAL::isa('UNIVERSAL', 'UNIVERSAL') ), "true", "map UNIVERSAL::isa('UNIVERSAL', 'UNIVERSAL') to true");
50+
51+
# GH #39
52+
# XS function utf8::is_utf8 returns sv_no or sv_yes
53+
SKIP: {
54+
skip 'Perl 5.8 is needed for boolean tests based on utf8::upgrade()+utf8::is_utf8()', 4 if $] < 5.008;
55+
is( $nonref_cjson->encode( do{utf8::is_utf8(my $a)} ), "false", "map do{utf8::is_utf8(my \$a)} to false");
56+
is( $nonref_cjson->encode( do{utf8::is_utf8(my $a)} ), "false", "map do{utf8::is_utf8(my \$a)} to false");
57+
my $utf8 = '';
58+
utf8::upgrade($utf8);
59+
is( $nonref_cjson->encode( do{utf8::is_utf8($utf8)} ), "true", "map do{utf8::is_utf8(\$utf8)} to true");
60+
is( $nonref_cjson->encode( do{utf8::is_utf8($utf8)} ), "true", "map do{utf8::is_utf8(\$utf8)} to true");
4361
}
62+
63+
# GH #39
64+
# perl expression which evaluates to sv_no or sv_yes
65+
SKIP: {
66+
# implemented in 5.16 but broken, works since 5.20
67+
skip 'Perl 5.20 is needed for boolean tests based on !1 and !0', 4 if $] < 5.020;
68+
is( $nonref_cjson->encode( !1 ), "false", "map !1 to false");
69+
is( $nonref_cjson->encode( !1 ), "false", "map !1 to false");
70+
is( $nonref_cjson->encode( !0 ), "true", "map !0 to true");
71+
is( $nonref_cjson->encode( !0 ), "true", "map !0 to true");
72+
}
73+
4474
$js = $cjson->decode( $truefalse );
4575
ok ($js->[0] == $true, "decode true to yes");
4676
ok ($js->[1] == $false, "decode false to no");
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use Test::More tests => 4;
2+
use Cpanel::JSON::XS;
3+
4+
my $json = Cpanel::JSON::XS->new;
5+
6+
# disallow dupkeys:
7+
ok (!eval { $json->decode ('{"a":"b","a":"c"}') }); # y_object_duplicated_key.json
8+
ok (!eval { $json->decode ('{"a":"b","a":"b"}') }); # y_object_duplicated_key_and_value.json
9+
10+
$json->relaxed;
11+
is (encode_json $json->decode ('{"a":"b","a":"c"}'), '{"a":"c"}'); # y_object_duplicated_key.json
12+
is (encode_json $json->decode ('{"a":"b","a":"b"}'), '{"a":"b"}'); # y_object_duplicated_key_and_value.json
13+

0 commit comments

Comments
 (0)