diff -Nru libcpanel-json-xs-perl-3.0225/.appveyor.yml libcpanel-json-xs-perl-3.0239/.appveyor.yml --- libcpanel-json-xs-perl-3.0225/.appveyor.yml 1970-01-01 00:00:00.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/.appveyor.yml 2017-07-29 15:18:21.000000000 +0000 @@ -0,0 +1,48 @@ +version: 3.02.31.{build} +skip_tags: true +#os: MinGW +#os: Visual Studio 2015 +#os: Default Azure +#build: +# verbosity: minimal +# there's no 32bit installer +platform: + - x64 + - x86 +environment: + matrix: + - STRAWBERRY: 1 + - MSVC_CPERL: 1 +clone_depth: 1 +init: + - git config --global core.autocrlf input + # Disable popups as they hang the build as there is nobody to click on the OK button... + # Hanging the build is a lot less user friendly than reporting a build failure. + # + # Disable of system hard error popup + # See: https://msdn.microsoft.com/en-us/library/bb513638%28VS.85%29.aspx + - reg add "HKLM\SYSTEM\CurrentControlSet\Control\Windows" /f /v ErrorMode /d 2 + # Disable the following popup on program failure: + # | ** has stopped working ** | + # | Windows can check online for a solution to the problem| + # | - Check online for a solution and close the program | + # | - Close the program | + # See: https://msdn.microsoft.com/en-us/library/bb513638%28VS.85%29.aspx + - reg add "HKLM\Software\Microsoft\Windows\Windows Error Reporting" /f /v DontShowUI /d 1 + #- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + +install: + - cinst wget -y + - if "%PLATFORM%" == "x86" set BITS=32 + - if "%PLATFORM%" == "x64" set BITS=64 + #- if "%STRAWBERRY%" == "1" wget -q http://strawberryperl.com/download/5.24.1.1/strawberry-perl-5.24.1.1-%BITS%bit.msi + # waits for input + #- if "%STRAWBERRY%" == "1" msiexec /qn /norestart strawberry-perl-5.24.1.1-%BITS%bit.msi + - if "%STRAWBERRY%" == "1" cinst strawberryperl -i + - if "%MSVC_CPERL%" == "1" wget -q https://github.com/perl11/cperl/releases/download/cperl-5.26.0/cperl-5.26.0-win%BITS%.exe + - if "%MSVC_CPERL%" == "1" cperl-5.26.0-win%BITS%.exe -y -o"C:\" + +build: off + +test_script: + - 't\appveyor-test.bat' diff -Nru libcpanel-json-xs-perl-3.0225/Changes libcpanel-json-xs-perl-3.0239/Changes --- libcpanel-json-xs-perl-3.0225/Changes 2016-11-23 18:30:10.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/Changes 2017-08-28 18:55:10.000000000 +0000 @@ -2,6 +2,78 @@ TODO: http://stevehanov.ca/blog/index.php?id=104 compression +3.0239 2017-08-28 (rurban) + - Fix compilation under windows. (#98 mauke) + +3.0238 2017-08-25 (rurban) + - Make printing of numbers on perl's earlier than 5.22 locale + insensitive, to produce a dot as decimal sep. (#96) + +3.0237 2017-07-28 (rurban) + - relax inf/nan tests as in t/op/infnan.t for windows. + we cannot know if msvcrt.dll or the new ucrt.dll is used. + try a list of valid values. + +3.0236 2017-07-27 (rurban) + - Stringify true again as "1", not as "true" due to popular demand. + (haarg #87) + +3.0235 2017-07-27 (rurban) + - Disallow duplicate keys by default, only allow them in relaxed + mode. (#75) + Analog to invalid unicode, which does error by default. + RFC 7159 section 4 says that "The names within an object should be unique." + So it's either i_ (undefined) or n_ (errors). + See http://seriot.ch/parsing_json.php#24 + This is different to the other JSON modules, which do have a different + interpretation of the spec. Use relaxed for backcompat if you want to + allow duplicate keys. + - De-fragilize t/96_mojo.t false test to "". It mostly is. + +3.0234 2017-07-27 (rurban) + - Fix and unify utf8 handling with 5.6.2 + and improve many utf8 tests. (pali #88) + - Add tests for boolean sv_yes and sv_no (pali #88) + - Check for correct module in %INC (Patrick Cronin #89) + - Fix appveyor smoke with latest strawberry, use $Config{make} (pali #91) + - Fix inf/nan for strawberry 5.26 + +3.0233 2017-05-01 (rurban) + - 5.6 test fixes, silence some cc warnings, + add coverage and release targets, fix appveyor + +3.0232 2017-04-30 (rurban) + - Fix for MSVC 2015/14.0 and newer with changed nan/inf. #85 + - Added appveyor CI + - Silence 32bit debugging format warning + - stabilize decode_hv hook (Coverity) + - ignore sv_utf8_downgrade errors (Coverity) + +3.0231 2017-03-29 (rurban) + - Fix need() overallocation (#84 Matthew Horsfall) and missing + need() calls. + +3.0230 2017-03-12 (rurban) + - Relax -Werror=declaration-after-statement for older gcc < 4.2 + +3.0229 2017-03-10 (rurban) + - fix minor gcc compilation warnings. + - Add some core compat. warnings for gcc/clang compat. compilers. + +3.0228 2017-03-08 (rurban) + - fix decode_prefix offset when the string was re-allocated. + rather return the offset not the pointer to the old start. (#82 PaulGWebster) + +3.0227 2017-02-13 (rurban) + - fix CLONE and END, broken with 3.0226 (#80 y). + These methods are usually called with arguments, which we ignore. + +3.0226 2017-02-11 (rurban) + - relax longdouble Gconvert test on ppc64le and aarch64-linux-ld, + with apparent HW quadmath without USE_QUADMATH (older perls). + (detected by dgolden) + - Fixed 2 uninit warnings in the XS + 3.0225 2016-11-23 (rurban) - decode utf8 security fixes for perl 5.6. added extra detection code for overflows and non-continuations. diff -Nru libcpanel-json-xs-perl-3.0225/debian/changelog libcpanel-json-xs-perl-3.0239/debian/changelog --- libcpanel-json-xs-perl-3.0225/debian/changelog 2017-07-27 06:25:43.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/debian/changelog 2017-10-03 10:12:24.000000000 +0000 @@ -1,8 +1,12 @@ -libcpanel-json-xs-perl (3.0225-1build1) artful; urgency=medium +libcpanel-json-xs-perl (3.0239-1) unstable; urgency=medium - * Rebuild against perl 5.26.0. + * Team upload. + * Import upstream version 3.0239. + * debian/control: declare compliance with Debian Policy 4.1.1. + * Update upstream contact in d/copyright and d/u/metadata. + * Add lintian override for long code line. - -- Gianfranco Costamagna Thu, 27 Jul 2017 08:25:43 +0200 + -- Nuno Carvalho Tue, 03 Oct 2017 11:12:24 +0100 libcpanel-json-xs-perl (3.0225-1) unstable; urgency=medium diff -Nru libcpanel-json-xs-perl-3.0225/debian/control libcpanel-json-xs-perl-3.0239/debian/control --- libcpanel-json-xs-perl-3.0225/debian/control 2016-12-28 19:40:23.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/debian/control 2017-10-03 10:12:24.000000000 +0000 @@ -10,7 +10,7 @@ libmojolicious-perl, libtest-leaktrace-perl, perl -Standards-Version: 3.9.8 +Standards-Version: 4.1.1 Vcs-Browser: https://anonscm.debian.org/cgit/pkg-perl/packages/libcpanel-json-xs-perl.git Vcs-Git: https://anonscm.debian.org/git/pkg-perl/packages/libcpanel-json-xs-perl.git Homepage: https://metacpan.org/release/Cpanel-JSON-XS diff -Nru libcpanel-json-xs-perl-3.0225/debian/copyright libcpanel-json-xs-perl-3.0239/debian/copyright --- libcpanel-json-xs-perl-3.0225/debian/copyright 2016-12-28 19:40:23.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/debian/copyright 2017-10-03 10:12:24.000000000 +0000 @@ -1,6 +1,6 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Source: https://metacpan.org/release/Cpanel-JSON-XS -Upstream-Contact: Reini Urban +Upstream-Contact: Reini Urban Upstream-Name: Cpanel-JSON-XS Files: * diff -Nru libcpanel-json-xs-perl-3.0225/debian/libcpanel-json-xs-perl.lintian-overrides libcpanel-json-xs-perl-3.0239/debian/libcpanel-json-xs-perl.lintian-overrides --- libcpanel-json-xs-perl-3.0225/debian/libcpanel-json-xs-perl.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/debian/libcpanel-json-xs-perl.lintian-overrides 2017-10-03 10:12:24.000000000 +0000 @@ -0,0 +1,2 @@ +# long code line +libcpanel-json-xs-perl: manpage-has-errors-from-man usr/share/man/man1/cpanel_json_xs.1p.gz 155: warning [p 1, 9.0i]: can't break line diff -Nru libcpanel-json-xs-perl-3.0225/debian/upstream/metadata libcpanel-json-xs-perl-3.0239/debian/upstream/metadata --- libcpanel-json-xs-perl-3.0225/debian/upstream/metadata 2016-12-28 19:40:23.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/debian/upstream/metadata 2017-10-03 10:12:24.000000000 +0000 @@ -1,6 +1,6 @@ --- Archive: CPAN Bug-Database: https://github.com/rurban/Cpanel-JSON-XS/issues -Contact: Reini Urban +Contact: Reini Urban Name: Cpanel-JSON-XS Repository: https://github.com/rurban/Cpanel-JSON-XS diff -Nru libcpanel-json-xs-perl-3.0225/Makefile.PL libcpanel-json-xs-perl-3.0239/Makefile.PL --- libcpanel-json-xs-perl-3.0225/Makefile.PL 2016-04-13 10:24:43.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/Makefile.PL 2017-07-27 20:28:41.000000000 +0000 @@ -1,6 +1,17 @@ use 5.006002; use ExtUtils::MakeMaker; -use Config (); +use Config; + +my $define = ''; +# https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Warning-Options.html +if ($Config{gccversion} and $Config{gccversion} =~ /^(\d+\.\d+)\./) { + my $gccver = $1; + if ($gccver >= 4.3) { + $define = '-Wall -Werror=declaration-after-statement -Wextra -W'; + } elsif ($gccver >= 3.4) { + $define = '-Wall -Wdeclaration-after-statement -Wextra -W'; + } +} WriteMakefile( dist => { @@ -14,10 +25,11 @@ PREREQ_PM => { 'Pod::Text' => '2.08', }, - LICENSE => 'perl', + DEFINE => $define, + LICENSE => 'perl', ($] >= 5.005 ? (ABSTRACT_FROM => 'XS.pm', - AUTHOR => 'Reini Urban ', + AUTHOR => 'Reini Urban ', # ORIGINAL_AUTHOR => 'Marc Lehmann ' ) : ()), ($ExtUtils::MakeMaker::VERSION gt '6.46' @@ -55,7 +67,6 @@ bugtracker => 'https://github.com/rurban/Cpanel-JSON-XS/issues', # Note: https://rt.cpan.org/Public/Dist/Display.html?Queue=Cpanel-JSON-XS is also observed repository => 'https://github.com/rurban/Cpanel-JSON-XS', - homepage => 'http://software.schmorp.de/pkg/JSON-XS.html', }, } ) : ()), @@ -82,5 +93,36 @@ " README : \$(VERSION_FROM) pod2text \$(VERSION_FROM) > README + +release : dist + git tag \$(VERSION) + cpan-upload \$(DISTVNAME).tar\$(SUFFIX) + git push + git push --tags + +const-c.inc const-xs.inc : Makefile.PL + +# versioned gcc needs overrides +GCOV = gcov +test_cover :: pure_all + \$(RM_RF) cover_db + +\$(PERLRUNINST) -S cover -test + +test_coveralls :: pure_all + +\$(PERLRUNINST) -S cover -test -report coveralls + +gcov : \$(BASEEXT).c.gcov \$(BASEEXT).gcov cover_db/\$(BASEEXT)-xs.html + +\$(BASEEXT).c.gcov \$(BASEEXT).xs.gcov : \$(BASEEXT).xs + \$(MAKE) CCFLAGS=\"\$(CCFLAGS) -fprofile-arcs -ftest-coverage\" LDDLFLAGS=\"\$(LDDLFLAGS) -fprofile-arcs -ftest-coverage\" + \$(GCOV) \$(BASEEXT).c \$(BASEEXT).xs + +cover_db/\$(BASEEXT)-xs.html : \$(BASEEXT).xs.gcov + PERL5OPT=-MDevel::Cover make test + -$^X -S gcov2perl \$(BASEEXT).c.gcov \$(BASEEXT).xs.gcov + $^X -S cover + +gprof : + \$(MAKE) CCFLAGS=\"\$(CCFLAGS) -pg\" LDDLFLAGS=\"\$(LDDLFLAGS) -pg\" " } diff -Nru libcpanel-json-xs-perl-3.0225/MANIFEST libcpanel-json-xs-perl-3.0239/MANIFEST --- libcpanel-json-xs-perl-3.0225/MANIFEST 2016-11-23 18:37:26.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/MANIFEST 2017-08-28 20:47:22.000000000 +0000 @@ -1,3 +1,4 @@ +.appveyor.yml .travis.yml README Changes @@ -38,6 +39,7 @@ t/23_array_ctx.t t/24_freeze_recursion.t t/25_boolean.t +t/26_duplicate.t t/30_jsonspec.t t/31_bom.t t/52_object.t @@ -45,6 +47,7 @@ t/54_stringify.t t/55_modifiable.t t/96_interop.t +t/96_interop_pp.t t/96_mojo.t t/97_unshare_hek.t t/98_56only.t @@ -62,6 +65,7 @@ t/115_tie_ixhash.t t/116_incr_parse_fixed.t t/117_numbers.t +t/appveyor-test.bat t/gh70-asan.t t/_unicode_handling.pm t/test_parsing/i_number_neg_int_huge_exp.json diff -Nru libcpanel-json-xs-perl-3.0225/META.json libcpanel-json-xs-perl-3.0239/META.json --- libcpanel-json-xs-perl-3.0225/META.json 2016-11-23 18:37:26.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/META.json 2017-08-28 20:47:22.000000000 +0000 @@ -1,16 +1,16 @@ { "abstract" : "cPanel fork of JSON::XS, fast and correct serializing", "author" : [ - "Reini Urban " + "Reini Urban " ], "dynamic_config" : 1, - "generated_by" : "ExtUtils::MakeMaker version 8.0403, CPAN::Meta::Converter version 2.150010", + "generated_by" : "ExtUtils::MakeMaker version 7.3, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", - "version" : "2" + "version" : 2 }, "name" : "Cpanel-JSON-XS", "no_index" : { @@ -41,7 +41,6 @@ "bugtracker" : { "web" : "https://github.com/rurban/Cpanel-JSON-XS/issues" }, - "homepage" : "http://software.schmorp.de/pkg/JSON-XS.html", "license" : [ "http://dev.perl.org/licenses/" ], @@ -49,6 +48,6 @@ "url" : "https://github.com/rurban/Cpanel-JSON-XS" } }, - "version" : "3.0225", - "x_serialization_backend" : "JSON::PP version 2.27400" + "version" : "3.0239", + "x_serialization_backend" : "JSON::PP version 2.94" } diff -Nru libcpanel-json-xs-perl-3.0225/META.yml libcpanel-json-xs-perl-3.0239/META.yml --- libcpanel-json-xs-perl-3.0225/META.yml 2016-11-23 18:37:26.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/META.yml 2017-08-28 20:47:22.000000000 +0000 @@ -1,13 +1,13 @@ --- abstract: 'cPanel fork of JSON::XS, fast and correct serializing' author: - - 'Reini Urban ' + - 'Reini Urban ' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 -generated_by: 'ExtUtils::MakeMaker version 8.0403, CPAN::Meta::Converter version 2.150010' +generated_by: 'ExtUtils::MakeMaker version 7.3, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html @@ -21,8 +21,7 @@ Pod::Text: '2.08' resources: bugtracker: https://github.com/rurban/Cpanel-JSON-XS/issues - homepage: http://software.schmorp.de/pkg/JSON-XS.html license: http://dev.perl.org/licenses/ repository: https://github.com/rurban/Cpanel-JSON-XS -version: '3.0225' +version: '3.0239' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -Nru libcpanel-json-xs-perl-3.0225/ppport.h libcpanel-json-xs-perl-3.0239/ppport.h --- libcpanel-json-xs-perl-3.0225/ppport.h 2016-10-06 08:43:33.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/ppport.h 2017-07-27 20:15:44.000000000 +0000 @@ -4,9 +4,9 @@ /* ---------------------------------------------------------------------- - ppport.h -- Perl/Pollution/Portability Version 3.33_02 + ppport.h -- Perl/Pollution/Portability Version 3.35_02 - Automatically created by Devel::PPPort running under perl 5.025001. + Automatically created by Devel::PPPort running under perl 5.026000. Do NOT edit this file directly! -- Edit PPPort_pm.PL and the includes in parts/inc/ instead. @@ -21,7 +21,7 @@ =head1 NAME -ppport.h - Perl/Pollution/Portability version 3.33_02 +ppport.h - Perl/Pollution/Portability version 3.35_02 =head1 SYNOPSIS @@ -383,7 +383,7 @@ # Disable broken TRIE-optimization BEGIN { eval '${^RE_TRIE_MAXBUF} = -1' if $] >= 5.009004 && $] <= 5.009005 } -my $VERSION = 3.33_02; +my $VERSION = 3.35_02; my %opt = ( quiet => 0, diff -Nru libcpanel-json-xs-perl-3.0225/README libcpanel-json-xs-perl-3.0239/README --- libcpanel-json-xs-perl-3.0225/README 2016-11-23 18:37:29.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/README 2017-08-28 20:47:24.000000000 +0000 @@ -123,7 +123,8 @@ - interop for true/false overloading. JSON::XS, JSON::PP and Mojo::JSON representations for booleans are accepted and JSON::XS accepts Cpanel::JSON::XS booleans [#13, #37] Fixed overloading of booleans. - Cpanel::JSON::XS::true stringifies now to true, not 1. + Cpanel::JSON::XS::true stringifies again to "1", not "true", analog to + all other JSON modules. - native boolean mapping of yes and no to true and false, as in YAML::XS. In perl "!0" is yes, "!1" is no. The JSON value true maps to @@ -157,6 +158,8 @@ - #72 parsing of illegal unicode or non-unicode characters. + - #96 locale-insensitive numeric conversion + - public maintenance and bugtracker - use ppport.h, sanify XS.xs comment styles, harness C coding style @@ -166,12 +169,13 @@ - extended testsuite, passes all http://seriot.ch/parsing_json.html tests. In fact it is the only know JSON decoder which does so, while - being the fastest. + also being the fastest. - support many more options and methods from JSON::PP: stringify_infnan, allow_unknown, allow_stringify, allow_barekey, encode_stringify, allow_bignum, allow_singlequote, sort_by (partially), escape_slash, - convert_blessed, ... optional decode_json(, allow_nonref) arg + convert_blessed, ... optional decode_json(, allow_nonref) arg. relaxed + implements allow_dupkeys. - support all 5 unicode BOM's: UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE, encoding internally to UTF-8. @@ -541,6 +545,13 @@ { foo:"bar" } + * duplicate keys + + With relaxed decoding of duplicate keys does not error and are + silently accepted. See : + RFC 7159 section 4: "The names within an object should be + unique." + $json = $json->canonical ([$enable]) $enabled = $json->get_canonical If $enable is true (or missing), then the "encode" method will @@ -1301,7 +1312,7 @@ respectively. You can also use "\1" and "\0" or "!0" and "!1" directly if you want. - encode_json [Cpanel::JSON::XS::true, Cpanel::JSON::XS::true] # yields [false,true] + encode_json [Cpanel::JSON::XS::true, Cpanel::JSON::XS::true] # yields [false,true] encode_json [!1, !0] # yields [false,true] blessed objects @@ -1983,8 +1994,8 @@ AUTHOR Marc Lehmann , http://home.schmorp.de/ - Reini Urban , http://cpanel.net/ + Reini Urban MAINTAINER - Reini Urban + Reini Urban diff -Nru libcpanel-json-xs-perl-3.0225/SIGNATURE libcpanel-json-xs-perl-3.0239/SIGNATURE --- libcpanel-json-xs-perl-3.0225/SIGNATURE 2016-11-23 18:37:28.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/SIGNATURE 2017-08-28 20:47:23.000000000 +0000 @@ -14,24 +14,25 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -SHA1 7473e2b9cd191810a0531dcd0bed55a153acc497 .travis.yml +SHA1 b1dc76bb84e636c3d4a32dc6676ae3259fa25aeb .appveyor.yml +SHA1 dc43f44fb1538b019f6b00c3b761bcdef76e7d2b .travis.yml SHA1 9a56f3b919dfc8fced3803e165a2e38de62646e5 COPYING -SHA1 0eca63583004e23c85152568093cffc27d32fc6a Changes -SHA1 7ebf5876b2d33d6ddcfd69e2541394c63537fcfd MANIFEST -SHA1 c3b7f25a966e88510f9724acb1947d57175c2331 META.json -SHA1 df66f431b2870bd559872ce6dbb12081fd50a1d7 META.yml -SHA1 326673d83f68b486d22267c540f457f55cd91c76 Makefile.PL -SHA1 c14d9febccd6bdcb718cae6a307b9c7a0cb4dfea README -SHA1 533e03d4469a48de286155ecd1dab2fe5dde0d77 XS.pm -SHA1 72a97b626375f9dc02a022d5687bb2d7de238880 XS.xs +SHA1 0370d23d2788a9fff4b11b3da04e2c894726a84d Changes +SHA1 1cb5b409cb86b392753ca0ea2d6ba718f104b128 MANIFEST +SHA1 80f61782c08de2746de12e5d1013940e12bb239c META.json +SHA1 98dc4055706e8f13b795a76b519fd6e29be14a9c META.yml +SHA1 9f4e725e4e2fa7e255d1fce4314446c77da64035 Makefile.PL +SHA1 13237f66b5b6778d16cb6b3b272982de5915348d README +SHA1 a03084f5e53fb04ca5a321a6d08df75554cba08c XS.pm +SHA1 57678a8bc9cf245050947691fcf4c34defdd0885 XS.xs SHA1 27b0bc7e0cd6fe90876fb3d285065c6a07cca028 XS/Boolean.pm SHA1 9e4b04d1af085e6959aaed51734475d350136392 bin/cpanel_json_xs SHA1 ea72bbe602baaabdd0004ef1d7e7cc3334b42bb4 eg/bench -SHA1 4adab19c45378f079298d6d0b9f90a57f55bafe7 ppport.h +SHA1 6e5d2153e1931be4e416c8feef7f7dfcab0f91b4 ppport.h SHA1 f7101031fd3fde35fe2421a07ab6cee8a822c00c t/00_load.t -SHA1 2e04c54c8e6bf0d8090bcbc17487238a98f5e0aa t/01_utf8.t +SHA1 c8f0471da3ab4cab5e197a5362e24c0e2958f589 t/01_utf8.t SHA1 9cf542e0bf68c90749420c7d07d7be80e1860592 t/02_error.t -SHA1 1dbcee8e27652d901af1c7f03a06a081e3b69092 t/03_types.t +SHA1 7ceff3f6fafe1ca6c3bb1c6e3042178753966013 t/03_types.t SHA1 d876bdffc381f4f67ec90f9c331e3ec2138946e2 t/04_dwiw_encode.t SHA1 94b1130a9b760102e0a24ad518f1e7439ef9122c t/05_dwiw_decode.t SHA1 d8c75d0fc7061469eba29275eb366b593c156f7d t/06_pc_pretty.t @@ -46,14 +47,14 @@ SHA1 446e9e23fbb26aca73c0c1cb168c6c31a68c9fb8 t/108_decode.t SHA1 d4d774595e581777fb13219a211c819c1d2f8575 t/109_encode.t SHA1 849b88cb5f17ca6c2324c78e1c4cb1d7857caccb t/10_pc_keysort.t -SHA1 cb666101c085d398374238e991624e703220c39b t/110_bignum.t +SHA1 c7eafd2e355b664d969f9ca2d5a9874e70cc0396 t/110_bignum.t SHA1 b007b686bb590e5eed3976edc78310437ae169d4 t/112_upgrade.t SHA1 01a0a0644343059c7185cb0b3b00b869d5211e1d t/113_overloaded_eq.t -SHA1 bcd500ccfc0cfb65c3ce4a4fa101ce8f72b5450d t/114_decode_prefix.t +SHA1 8dece990d5b07df0ae1b6364caefced774cb587d t/114_decode_prefix.t SHA1 eb050780996f1e428c87bf6375415ca4c863cbb2 t/115_tie_ixhash.t SHA1 3477b0490b8666e451ac15df97f9f35d72c946b1 t/116_incr_parse_fixed.t -SHA1 563cf24c85f22a077a9c20a0dfee1052db289b66 t/117_numbers.t -SHA1 85b8ecea1edf2bb92ecc2e1199e0a499a6bb07d2 t/11_pc_expo.t +SHA1 25ca035b576130cf560953df4e9daf68bdd96c3c t/117_numbers.t +SHA1 d1003d09b5da3609977362bcda64b2c593039a6b t/11_pc_expo.t SHA1 c0037e62cefc891df4bb84a110051963a60e9f8c t/12_blessed.t SHA1 4d553fd6b5e4486f087babff2946e0cb4b2c38fb t/13_limit.t SHA1 2b843abe875bf080d0c949663e32105a13c38122 t/14_latin1.t @@ -63,24 +64,27 @@ SHA1 1523ef12859072ba900344df5f1a8439c74fbad2 t/18_json_checker.t SHA1 33231a52e12866a61c405496947827485ff2a811 t/19_incr.t SHA1 8f266979e62b50271f353e5e6905e52d9038834b t/20_faihu.t -SHA1 37a646a883e0f1adc57ed88a1492d8273379ba84 t/20_unknown.t +SHA1 562b9329aff83c441b29815e3987b467d0e983e4 t/20_unknown.t SHA1 1d9c81e5dfc27ff7f790354ce22af335cefe09c2 t/21_evans.t SHA1 3d155f37e687f929bd0cae767dc2dbf1993b73c9 t/22_comment_at_eof.t SHA1 1ffb0242c800720c565a9e148e184bfa9d54b1c4 t/23_array_ctx.t SHA1 2d2ccc7877250f80755a74acd0c3c2f21e606aae t/24_freeze_recursion.t -SHA1 de63833eb7d922d21339a210680ebf84508b987a t/25_boolean.t -SHA1 91f4a7a000fe4b7170945466a8e37fe20a55082c t/30_jsonspec.t -SHA1 8eadf9f4a1c9958e19f9fcf1dd7194f87967e7bf t/31_bom.t +SHA1 bc1bf7bba31c320aed7164fe377957a0f6a8be57 t/25_boolean.t +SHA1 b731e24e61fd24c19c7b2e636bf20b368fbc851e t/26_duplicate.t +SHA1 7f4c74f3c46477c513a2baf07a60c94969d2e0e9 t/30_jsonspec.t +SHA1 3705a4bc706627dde26e444f41342b88850cbe98 t/31_bom.t SHA1 ded6191143511074b0cfa5c7ff990e0cbaa11ff9 t/52_object.t SHA1 292cb103dae404294cb77c68e3f28a1239f603b9 t/53_readonly.t SHA1 cf201da353d9930435463aee512fa7dccbad96df t/54_stringify.t SHA1 f08d2ec9499dc0d0e5ede5691c75b865f466b69c t/55_modifiable.t SHA1 7ad4a15bfdec5bbd757a48a4670f0275fb2ffd71 t/96_interop.t -SHA1 711a469b7cf72b40bbe94ce65264d1c0a3f0a016 t/96_mojo.t +SHA1 1caf7492922f42dd78cf34b2de7bba5481f84fd8 t/96_interop_pp.t +SHA1 758322045b9e08bfd98122a662950eb86efb7180 t/96_mojo.t SHA1 3291c73ec3a19df551d0fff59695153616fc982a t/97_unshare_hek.t SHA1 1bf6336a76101f747b84c35cca38c4e8bacb9224 t/98_56only.t SHA1 e5e4ea9e68154f9adb4e5e19a86c96efb1704d02 t/99_binary.t SHA1 e6078e2fc5c375d45498494bb91487834601a189 t/_unicode_handling.pm +SHA1 ef62decbf1634f795ef03babe0b36ab9855f263b t/appveyor-test.bat SHA1 483157c2a683750b52011f4b6cc00fc3b4381d9a t/gh70-asan.t SHA1 413be8df242f37f68aa3841888174e545cba5b2f t/test_parsing/i_number_neg_int_huge_exp.json SHA1 fa1cc74fc07e84b1a18883a4f5e85472c41df793 t/test_parsing/i_number_pos_double_huge_exp.json @@ -421,16 +425,16 @@ SHA1 5cd847ba5ed5d1a90807dbf8891bf1690918cb5e t/z_kwalitee.t SHA1 6dfd7f5112f80b65e84916c780a0b1a71aad32dc t/z_leaktrace.t SHA1 e3259ac6c4bd7f3349cf6f2ff829827483bc749d t/z_meta.t -SHA1 741e9e8bf600c7f7441794fe49ea8904cfd4bf58 t/z_perl_minimum_version.t +SHA1 204e8376b847824292d6630be5b0ecfb54ad9a2b t/z_perl_minimum_version.t SHA1 d91cc1b39fcb1dbf23c11ebb5885cfaaeb2c3a50 t/z_pod-coverage.t SHA1 2eb526b1649c6306df677d7ae63433856b672476 t/z_pod-spell-mistakes.t -SHA1 6f532d207153835d9abe3360d85cb8f00c09bbfe t/z_pod-spelling.t +SHA1 6e74cfbeb5080643d126b9d74f2f7e6dad26b013 t/z_pod-spelling.t SHA1 8db603172315dd0853ecc383dba4945c5b673e8f t/z_pod.t SHA1 3b92cafada1b683bbf03593d22eb40671e744bc7 t/zero-mojibake.t SHA1 e93c9b53438be114c25aa426742e24f4343057a7 typemap -----BEGIN PGP SIGNATURE----- -iEUEARECAAYFAlg14eYACgkQmm2SYo/9yUIi3QCYieGKtBzH0GSR0h4OXSSP1c3s -+ACeOJJKpuCzdkrscHxFj9eBs7Pyg/8= -=v46H +iF0EARECAB0WIQRZHhhUcL58V8z0UW2abZJij/3JQgUCWaSBWwAKCRCabZJij/3J +QvrLAJ0bTW8cqyjtMaUxI/hQyWK7BG1mwQCeKMS2zGSNV4YB6uVOXH4Xv0Ck2rI= +=q1+r -----END PGP SIGNATURE----- diff -Nru libcpanel-json-xs-perl-3.0225/t/01_utf8.t libcpanel-json-xs-perl-3.0239/t/01_utf8.t --- libcpanel-json-xs-perl-3.0225/t/01_utf8.t 2016-11-23 18:21:40.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/01_utf8.t 2017-07-27 20:15:44.000000000 +0000 @@ -1,72 +1,76 @@ -use Test::More tests => 155; +use Test::More tests => 162; use utf8; use Cpanel::JSON::XS; +use warnings; -is(Cpanel::JSON::XS->new->allow_nonref (1)->utf8 (1)->encode ("ü"), "\"\xc3\xbc\""); -is(Cpanel::JSON::XS->new->allow_nonref (1)->encode ("ü"), "\"ü\""); +is(Cpanel::JSON::XS->new->allow_nonref->utf8->encode("ü"), "\"\xc3\xbc\""); +is(Cpanel::JSON::XS->new->allow_nonref->encode("ü"), "\"ü\""); -is(Cpanel::JSON::XS->new->allow_nonref (1)->ascii (1)->utf8 (1)->encode (chr 0x8000), '"\u8000"'); -is(Cpanel::JSON::XS->new->allow_nonref (1)->ascii (1)->utf8 (1)->pretty (1)->encode (chr 0x10402), "\"\\ud801\\udc02\"\n"); +is(Cpanel::JSON::XS->new->allow_nonref->ascii->utf8->encode(chr 0x8000), '"\u8000"'); +is(Cpanel::JSON::XS->new->allow_nonref->ascii->utf8->pretty->encode(chr 0x10402), "\"\\ud801\\udc02\"\n"); + +ok not defined eval { Cpanel::JSON::XS->new->allow_nonref->utf8->decode('"ü"') }; +like $@, qr/malformed UTF-8/; + +is(Cpanel::JSON::XS->new->allow_nonref->decode('"ü"'), "ü"); +is(Cpanel::JSON::XS->new->allow_nonref->decode('"\u00fc"'), "ü"); + +ok not defined eval { decode_json ('"\ud801\udc02' . "\x{10204}\"", 1) }; +like $@, qr/Wide character/; SKIP: { skip "5.6", 1 if $] < 5.008; - eval { Cpanel::JSON::XS->new->allow_nonref (1)->utf8 (1)->decode ('"ü"') }; - like $@, qr/malformed UTF-8/; + is(Cpanel::JSON::XS->new->allow_nonref->decode('"\ud801\udc02' . "\x{10204}\""), "\x{10402}\x{10204}"); } -is(Cpanel::JSON::XS->new->allow_nonref (1)->decode ('"ü"'), "ü"); -is(Cpanel::JSON::XS->new->allow_nonref (1)->decode ('"\u00fc"'), "ü"); -if ($] < 5.008) { - eval { decode_json ('"\ud801\udc02' . "\x{10204}\"", 1) }; - like $@, qr/malformed UTF-8/; -} else { - is(Cpanel::JSON::XS->new->allow_nonref (1)->decode ('"\ud801\udc02' . "\x{10204}\""), "\x{10402}\x{10204}"); -} -is(Cpanel::JSON::XS->new->allow_nonref (1)->decode ('"\"\n\\\\\r\t\f\b"'), "\"\012\\\015\011\014\010"); +is(Cpanel::JSON::XS->new->allow_nonref->decode('"\"\n\\\\\r\t\f\b"'), "\"\012\\\015\011\014\010"); -my $love = $] < 5.008 ? "I \342\235\244 perl" : "I ❤ perl"; -is(Cpanel::JSON::XS->new->ascii->encode ([$love]), - $] < 5.008 ? '["I \u00e2\u009d\u00a4 perl"]' : '["I \u2764 perl"]', 'utf8 enc ascii'); -is(Cpanel::JSON::XS->new->latin1->encode ([$love]), - $] < 5.008 ? "[\"I \342\235\244 perl\"]" : '["I \u2764 perl"]', 'utf8 enc latin1'); +my $utf8_love = "I \342\235\244 perl"; +is(Cpanel::JSON::XS->new->ascii->encode([$utf8_love]), '["I \u00e2\u009d\u00a4 perl"]', 'utf8 enc ascii'); +is(Cpanel::JSON::XS->new->latin1->encode([$utf8_love]), "[\"I \342\235\244 perl\"]", 'utf8 enc latin1'); +is(Cpanel::JSON::XS->new->utf8->encode([$utf8_love]), "[\"I \303\242\302\235\302\244 perl\"]", 'utf8 enc utf8'); +is(Cpanel::JSON::XS->new->binary->encode([$utf8_love]), '["I \xe2\x9d\xa4 perl"]', 'utf8 enc binary'); SKIP: { - skip "5.6", 1 if $] < 5.008; - require Encode; - # [RT #84244] wrong complaint: JSON::XS double encodes to ["I ❤ perl"] - # and with utf8 triple encodes it to ["I ❤ perl"] - if ($Encode::VERSION < 2.40 or $Encode::VERSION >= 2.54) { # Encode stricter check: Cannot decode string with wide characters - # see also http://stackoverflow.com/questions/12994100/perl-encode-pm-cannot-decode-string-with-wide-character - $love = "I \342\235\244 perl"; - } - my $s = Encode::decode_utf8($love); # User tries to double decode wide-char to unicode with Encode - is(Cpanel::JSON::XS->new->utf8->encode ([$s]), "[\"I \342\235\244 perl\"]", 'utf8 enc utf8 [RT #84244]'); + skip "5.6", 4 if $] < 5.008; + my $unicode_love = "I ❤ perl"; + is(Cpanel::JSON::XS->new->ascii->encode([$unicode_love]), '["I \u2764 perl"]', 'unicode enc ascii'); + is(Cpanel::JSON::XS->new->latin1->encode([$unicode_love]), "[\"I \\u2764 perl\"]", 'unicode enc latin1'); + is(Cpanel::JSON::XS->new->utf8->encode([$unicode_love]), "[\"I \342\235\244 perl\"]", 'unicode enc utf8'); + is(Cpanel::JSON::XS->new->binary->encode([$unicode_love]), '["I \xe2\x9d\xa4 perl"]', 'unicode enc binary'); } -is(Cpanel::JSON::XS->new->binary->encode ([$love]), '["I \xe2\x9d\xa4 perl"]', 'utf8 enc binary'); # TODO: test utf8 hash keys, # test utf8 strings without any char > 0x80. # warn on the 66 non-characters as in core { - my $w; - require warnings; - warnings->unimport($] < 5.014 ? 'utf8' : 'nonchar'); + BEGIN { 'warnings'->import($] < 5.014 ? 'utf8' : 'nonchar') } + my $w = ''; $SIG{__WARN__} = sub { $w = shift }; my $d = Cpanel::JSON::XS->new->allow_nonref->decode('"\ufdd0"'); my $warn = $w; - is ($d, "\x{fdd0}", substr($warn,0,31)."..."); + { + no warnings 'utf8'; + is ($d, "\x{fdd0}", substr($warn,0,31)."..."); + } like ($warn, qr/^Unicode non-character U\+FDD0 is/); $w = ''; # higher planes $d = Cpanel::JSON::XS->new->allow_nonref->decode('"\ud83f\udfff"'); $warn = $w; - is ($d, "\x{1ffff}", substr($warn,0,31)."..."); + { + no warnings 'utf8'; + is ($d, "\x{1ffff}", substr($warn,0,31)."..."); + } like ($w, qr/^Unicode non-character U\+1FFFF is/); $w = ''; $d = Cpanel::JSON::XS->new->allow_nonref->decode('"\ud87f\udffe"'); $warn = $w; - is ($d, "\x{2fffe}", substr($warn,0,31)."..."); + { + no warnings 'utf8'; + is ($d, "\x{2fffe}", substr($warn,0,31)."..."); + } like ($w, qr/^Unicode non-character U\+2FFFE is/); $w = ''; @@ -77,12 +81,15 @@ } { my $w; - warnings->unimport($] < 5.014 ? 'utf8' : 'nonchar'); + BEGIN { 'warnings'->import($] < 5.014 ? 'utf8' : 'nonchar') } $SIG{__WARN__} = sub { $w = shift }; # no warning with relaxed my $d = Cpanel::JSON::XS->new->allow_nonref->relaxed->decode('"\ufdd0"'); my $warn = $w; - is ($d, "\x{fdd0}", "no warning with relaxed"); + { + no warnings 'utf8'; + is ($d, "\x{fdd0}", "no warning with relaxed"); + } is($w, undef); } @@ -144,9 +151,9 @@ { # these are no multibyte codepoints, just raw utf8 bytes, # so most of them work with 5.6 also. - $^W = 1; + BEGIN { $^W = 1 } + BEGIN { 'warnings'->import($] < 5.014 ? 'utf8' : 'nonchar') } my $w; - warnings->import($] < 5.014 ? 'utf8' : 'nonchar'); $SIG{__WARN__} = sub { $w = shift }; for my $ill (@ill) { diff -Nru libcpanel-json-xs-perl-3.0225/t/03_types.t libcpanel-json-xs-perl-3.0239/t/03_types.t --- libcpanel-json-xs-perl-3.0225/t/03_types.t 2016-06-02 15:34:50.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/03_types.t 2017-07-27 20:15:44.000000000 +0000 @@ -22,7 +22,7 @@ ok ("$false" eq "0", "false: stringified $false eq 0"); #ok ("$false" eq "false", "false: stringified $false eq false"); #ok ("$true" eq "1", "true: stringified $true eq 1"); -ok ("$true" eq "true", "true: stringified $true"); +ok ("$true" eq "1", "true: stringified $true"); { my $FH; my $fn = "tmp_$$"; @@ -32,7 +32,7 @@ open $FH, "<", $fn; my $s = <$FH>; close $FH; - ok ($s eq "0true\n", $s); # 11 + ok ($s eq "01\n", $s); # 11 unlink $fn; } diff -Nru libcpanel-json-xs-perl-3.0225/t/110_bignum.t libcpanel-json-xs-perl-3.0239/t/110_bignum.t --- libcpanel-json-xs-perl-3.0225/t/110_bignum.t 2016-11-16 11:43:56.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/110_bignum.t 2017-03-29 09:51:37.000000000 +0000 @@ -38,7 +38,7 @@ $e = $json->encode($num); is($e, '2.0000000000000000001', 'encode bigfloat') or Dump $e; -my $num = $json->decode(q|[100000000000000000000000000000000000000]|)->[0]; +$num = $json->decode(q|[100000000000000000000000000000000000000]|)->[0]; isa_ok( $num, 'Math::BigInt' ); is( diff -Nru libcpanel-json-xs-perl-3.0225/t/114_decode_prefix.t libcpanel-json-xs-perl-3.0239/t/114_decode_prefix.t --- libcpanel-json-xs-perl-3.0225/t/114_decode_prefix.t 2015-11-30 16:17:08.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/114_decode_prefix.t 2017-03-29 09:51:37.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/perl use strict; -use Test::More tests => 8; +use Test::More tests => 12; use Cpanel::JSON::XS; @@ -23,3 +23,9 @@ eval { $json->decode_prefix( "\n" ) }; ok( $@ =~ /malformed JSON/ ); eval { $json->decode_prefix('null') }; ok $@ =~ /allow_nonref/; +my $buffer = "[0][1][2][3]"; +for (0..3) { + my ($data, $size) = $json->decode_prefix($buffer); + $buffer = substr($buffer,$size); + is ($size, 3, "advance offset $buffer #82"); +} diff -Nru libcpanel-json-xs-perl-3.0225/t/117_numbers.t libcpanel-json-xs-perl-3.0239/t/117_numbers.t --- libcpanel-json-xs-perl-3.0225/t/117_numbers.t 2016-10-28 08:31:16.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/117_numbers.t 2017-08-28 18:55:10.000000000 +0000 @@ -3,7 +3,7 @@ use Test::More; use Config; plan skip_all => "Yet unhandled inf/nan with $^O" if $^O eq 'dec_osf'; -plan tests => 24; +plan tests => 25; # infnan_mode = 0: is encode_json([9**9**9]), '[null]', "inf -> null stringify_infnan(0)"; @@ -16,6 +16,8 @@ my $json = Cpanel::JSON::XS->new->stringify_infnan; my $have_qnan = ($^O eq 'MSWin32' || $^O eq 'aix') ? 1 : 0; # TODO dec_osf +# variants as in t/op/infnan.t +my (@inf, @neg_inf, @nan, @neg_nan); my ($inf, $nan) = ($^O eq 'MSWin32') ? ('1.#INF','1.#QNAN') : ($^O eq 'solaris') ? ('Infinity','NaN') : @@ -30,12 +32,25 @@ ($^O eq 'hpux') ? "---" : "-".$inf; -if ($^O eq 'MSWin32' - and $Config{ccflags} =~ /-D__USE_MINGW_ANSI_STDIO/ - and $Config{uselongdouble}) -{ +if ($^O eq 'MSWin32' and $Config{ccflags} =~ /-D__USE_MINGW_ANSI_STDIO/) { $have_qnan = 0; ($inf, $neg_inf, $nan, $neg_nan) = ('inf','-inf','nan','-nan'); + @inf = ($inf); + @neg_inf = ($neg_inf); + @nan = ($nan); + @neg_nan = ($neg_nan); +} +elsif ($^O eq 'MSWin32') { # new ucrtd.dll + ($inf, $neg_inf, $nan, $neg_nan) = ('inf','-inf','nan','-nan'); + @inf = ('1.#INF', 'inf'); + @neg_inf = ('-1.#INF', '-inf'); + @nan = ('1.#QNAN', 'nan'); + @neg_nan = ('-1.#IND', '-nan', '-nan(ind)'); +} else { + @inf = ($inf); + @neg_inf = ($neg_inf); + @nan = ($nan); + @neg_nan = ($neg_nan); } # newlib and glibc 2.5 have no -nan support, just nan. The BSD's neither, but they might # come up with it lateron, as darwin did. @@ -43,27 +58,45 @@ # $neg_nan = $nan; #} +sub match { + my ($r, $tmpl, $desc, @list) = @_; + my $match = shift @list; + my $m = $tmpl; + $m =~ s/__XX__/$match/; + $match = $m; + for my $m1 (@list) { # at least one must match + $m = $tmpl; + $m =~ s/__XX__/$m1/; + diag "try $m eq $r" if $ENV{TEST_VERBOSE}; + $match = $m if $r eq $m; + } + is $r, $match, $desc; +} + my $r = $json->encode([9**9**9]); $r =~ s/\.0$// if $^O eq 'MSWin32'; -is $r, "[\"$inf\"]", "inf -> \"inf\" stringify_infnan(1)"; +match($r, "[\"__XX__\"]", "inf -> \"inf\" stringify_infnan(1)", @inf); + $r = $json->encode([-9**9**9]); $r =~ s/\.0$// if $^O eq 'MSWin32'; -is $r, "[\"$neg_inf\"]", "-inf -> \"-inf\""; +match($r, "[\"__XX__\"]", "-inf -> \"-inf\"", @neg_inf); + # The concept of negative nan is not portable and varies too much. # Windows even emits neg_nan for the first test sometimes. HP-UX has all tests reverse. -like $json->encode([-sin(9**9**9)]), qr/\[\"(\Q$neg_nan\E|\Q$nan\E)\"\]/, "nan -> \"nan\""; -like $json->encode([sin(9**9**9)]), qr/\[\"(\Q$neg_nan\E|\Q$nan\E)\"\]/, "-nan -> \"-nan\""; -like $json->encode([9**9**9/9**9**9]), qr/\[\"(\Q$neg_nan\E|\Q$nan\E)\"\]/, "-nan -> \"-nan\""; +match($json->encode([-sin(9**9**9)]), "[\"__XX__\"]", "nan -> \"nan\"", @nan, @neg_nan); +match($json->encode([sin(9**9**9)]), "[\"__XX__\"]", "-nan -> \"-nan\"", @nan, @neg_nan); +match($json->encode([9**9**9/9**9**9]), "[\"__XX__\"]", "-nan -> \"-nan\"", @nan, @neg_nan); # infnan_mode = 2: # inf/nan values, as in JSON::XS and older releases. $json = Cpanel::JSON::XS->new->stringify_infnan(2); -is $json->encode([9**9**9]), "[$inf]", "inf stringify_infnan(2)"; -is $json->encode([-9**9**9]), "[$neg_inf]", "-inf"; -like $json->encode([-sin(9**9**9)]), qr/\[(\Q$neg_nan\E|\Q$nan\E)\]/, "nan"; -like $json->encode([sin(9**9**9)]), qr/\[(\Q$neg_nan\E|\Q$nan\E)\]/, "-nan"; -like $json->encode([9**9**9/9**9**9]), qr/\[(\Q$neg_nan\E|\Q$nan\E)\]/, "-nan"; +match($json->encode([9**9**9]), "[__XX__]", "inf stringify_infnan(2)", @inf); +match($json->encode([-9**9**9]), "[__XX__]", "-inf", @neg_inf); +match($json->encode([-sin(9**9**9)]), "[__XX__]", "nan", @nan, @neg_nan); +match($json->encode([sin(9**9**9)]), "[__XX__]", "-nan", @nan, @neg_nan); +match($json->encode([9**9**9/9**9**9]), "[__XX__]", "-nan", @nan, @neg_nan); -# infnan_mode = 3: # inf/nan values unified to inf/-inf/nan strings. no qnan/snan/negative nan +# infnan_mode = 3: +# inf/nan values unified to inf/-inf/nan strings. no qnan/snan/negative nan $json = Cpanel::JSON::XS->new->stringify_infnan(3); is $json->encode([9**9**9]), '["inf"]', "inf stringify_infnan(3)"; is $json->encode([-9**9**9]), '["-inf"]', "-inf"; @@ -93,3 +126,10 @@ $resnum = ($] > 5.007 && $] <= 5.010) ? '23' : '23.0'; is encode_json({test => [$num, $str]}), qq|{"test":[$resnum,"bar"]}|, 'int/string dualvar'; + +{ + use POSIX qw(setlocale); + setlocale(&POSIX::LC_ALL, "fr_FR.utf-8"); + is encode_json({"invalid" => 123.45}), qq|{"invalid":123.45}|, + "numeric radix"; +} diff -Nru libcpanel-json-xs-perl-3.0225/t/11_pc_expo.t libcpanel-json-xs-perl-3.0239/t/11_pc_expo.t --- libcpanel-json-xs-perl-3.0225/t/11_pc_expo.t 2016-06-02 15:57:10.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/11_pc_expo.t 2017-03-29 09:51:37.000000000 +0000 @@ -38,6 +38,9 @@ $js = $pc->encode($obj); if ($Config::Config{usequadmath}) { is($js,'[1010000000000000000000000000000.0]', 'digit 1010000000000000000000000000000.0 (quadmath)'); +} elsif ($Config::Config{uselongdouble} && $Config::Config{ptrsize} > 4) { + like($js, qr/^\[(1010000000000000000000000000000\.0|1.01[Ee]\+0?30)\]/, + 'digit (64bit ld)'); # esp. non-intel } else { like($js,qr/\[1.01[Ee]\+0?30\]/, 'digit 1.01e+30'); } diff -Nru libcpanel-json-xs-perl-3.0225/t/20_unknown.t libcpanel-json-xs-perl-3.0239/t/20_unknown.t --- libcpanel-json-xs-perl-3.0225/t/20_unknown.t 2016-06-18 09:50:01.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/20_unknown.t 2017-07-27 20:15:44.000000000 +0000 @@ -3,15 +3,15 @@ use Test::More; BEGIN { # allow_unknown method added to JSON::PP in 2.09 - eval 'use JSON 2.09 (); 1' - or plan skip_all => 'JSON 2.09 required for cross testing'; + eval 'use JSON::PP 2.09 (); 1' + or plan skip_all => 'JSON::PP 2.09 required for cross testing'; $ENV{PERL_JSON_BACKEND} = 'JSON::PP'; } plan tests => 32; -use JSON (); +use JSON::PP (); use Cpanel::JSON::XS (); -my $pp = JSON->new; +my $pp = JSON::PP->new; my $json = Cpanel::JSON::XS->new; eval q| $json->encode( [ sub {} ] ) |; diff -Nru libcpanel-json-xs-perl-3.0225/t/25_boolean.t libcpanel-json-xs-perl-3.0239/t/25_boolean.t --- libcpanel-json-xs-perl-3.0225/t/25_boolean.t 2015-12-02 22:45:39.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/25_boolean.t 2017-07-29 15:18:21.000000000 +0000 @@ -1,19 +1,17 @@ use strict; -use Test::More tests => 17; +use Test::More tests => 32; use Cpanel::JSON::XS (); +use Config; my $booltrue = q({"is_true":true}); my $boolfalse = q({"is_false":false}); -# since 5.16 yes/no is !0/!1, but for earlier perls we need to use a BoolSV -my $a = 0; -my $yes = do{$a==0}; # < 5.16 !0 is not sv_yes -my $no = do{$a==1}; # < 5.16 !1 is not sv_no -my $yesno = [ $yes, $no ]; # native yes/no. YAML::XS compatible my $truefalse = "[true,false]"; my $cjson = Cpanel::JSON::XS->new; my $true = Cpanel::JSON::XS::true; my $false = Cpanel::JSON::XS::false; +my $nonref_cjson = Cpanel::JSON::XS->new->allow_nonref; + # from JSON::MaybeXS my $data = $cjson->decode('{"foo": true, "bar": false, "baz": 1}'); ok($cjson->is_bool($data->{foo}), 'true decodes to a bool') @@ -37,15 +35,54 @@ is( $cjson->encode( [ $true, $false] ), $truefalse ); -TODO: { - local $TODO = 'GH #39'; - is( $cjson->encode( $yesno ), $truefalse, "map yes/no to [true,false]"); +# GH #39 +# perl block which returns sv_no or sv_yes +is( $nonref_cjson->encode( do{(my $a=0)==1} ), "false", "map do{(my \$a)=0)==1} to false"); +is( $nonref_cjson->encode( do{(my $a=0)==1} ), "false", "map do{(my \$a)=0)==1} to false"); +is( $nonref_cjson->encode( do{(my $a=1)==1} ), "true", "map do{(my \$a)=1)==1} to true"); +is( $nonref_cjson->encode( do{(my $a=1)==1} ), "true", "map do{(my \$a)=1)==1} to true"); + +# GH #39 +# XS function UNIVERSAL::isa returns sv_no or sv_yes +is( $nonref_cjson->encode( UNIVERSAL::isa('0', '1') ), "false", "map UNIVERSAL::isa('0', '1') to false"); +is( $nonref_cjson->encode( UNIVERSAL::isa('0', '1') ), "false", "map UNIVERSAL::isa('0', '1') to false"); +is( $nonref_cjson->encode( UNIVERSAL::isa('UNIVERSAL', 'UNIVERSAL') ), "true", "map UNIVERSAL::isa('UNIVERSAL', 'UNIVERSAL') to true"); +is( $nonref_cjson->encode( UNIVERSAL::isa('UNIVERSAL', 'UNIVERSAL') ), "true", "map UNIVERSAL::isa('UNIVERSAL', 'UNIVERSAL') to true"); + +# GH #39 +# XS function utf8::is_utf8 returns sv_no or sv_yes +SKIP: { + skip 'Perl 5.8 is needed for boolean tests based on utf8::upgrade()+utf8::is_utf8()', 4 if $] < 5.008; + is( $nonref_cjson->encode( do{utf8::is_utf8(my $a)} ), "false", "map do{utf8::is_utf8(my \$a)} to false"); + is( $nonref_cjson->encode( do{utf8::is_utf8(my $a)} ), "false", "map do{utf8::is_utf8(my \$a)} to false"); + my $utf8 = ''; + utf8::upgrade($utf8); + is( $nonref_cjson->encode( do{utf8::is_utf8($utf8)} ), "true", "map do{utf8::is_utf8(\$utf8)} to true"); + is( $nonref_cjson->encode( do{utf8::is_utf8($utf8)} ), "true", "map do{utf8::is_utf8(\$utf8)} to true"); +} + +# GH #39 stringification. enabled with 5.16, stable fix with 5.20 +if ($] < 5.020 && $Config{useithreads}) { + # random results threaded + my ($strue, $sfalse) = (qr/^(1|true)$/, qr/^(""||false)$/); + like( $nonref_cjson->encode( !1 ), $sfalse, "map !1 to false"); + like( $nonref_cjson->encode( !1 ), $sfalse, "map !1 to false"); + like( $nonref_cjson->encode( !0 ), $strue, "map !0 to 1/true"); + like( $nonref_cjson->encode( !0 ), $strue, "map !0 to 1/true"); +} else { + # perl expression which evaluates to stable sv_no or sv_yes + my ($strue, $sfalse) = ("true", "false"); + is( $nonref_cjson->encode( !1 ), $sfalse, "map !1 to false"); + is( $nonref_cjson->encode( !1 ), $sfalse, "map !1 to false"); + is( $nonref_cjson->encode( !0 ), $strue, "map !0 to true"); + is( $nonref_cjson->encode( !0 ), $strue, "map !0 to true"); } + $js = $cjson->decode( $truefalse ); ok ($js->[0] == $true, "decode true to yes"); ok ($js->[1] == $false, "decode false to no"); -ok( Cpanel::JSON::XS::is_bool($js->[0]) ); -ok( Cpanel::JSON::XS::is_bool($js->[1]) ); +ok( Cpanel::JSON::XS::is_bool($js->[0]), "true is_bool"); +ok( Cpanel::JSON::XS::is_bool($js->[1]), "false is_bool"); # GH #53 -ok( !Cpanel::JSON::XS::is_bool( [] ) ); +ok( !Cpanel::JSON::XS::is_bool( [] ), "[] !is_bool"); diff -Nru libcpanel-json-xs-perl-3.0225/t/26_duplicate.t libcpanel-json-xs-perl-3.0239/t/26_duplicate.t --- libcpanel-json-xs-perl-3.0225/t/26_duplicate.t 1970-01-01 00:00:00.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/26_duplicate.t 2017-07-27 20:15:44.000000000 +0000 @@ -0,0 +1,13 @@ +use Test::More tests => 4; +use Cpanel::JSON::XS; + +my $json = Cpanel::JSON::XS->new; + +# disallow dupkeys: +ok (!eval { $json->decode ('{"a":"b","a":"c"}') }); # y_object_duplicated_key.json +ok (!eval { $json->decode ('{"a":"b","a":"b"}') }); # y_object_duplicated_key_and_value.json + +$json->relaxed; +is (encode_json $json->decode ('{"a":"b","a":"c"}'), '{"a":"c"}'); # y_object_duplicated_key.json +is (encode_json $json->decode ('{"a":"b","a":"b"}'), '{"a":"b"}'); # y_object_duplicated_key_and_value.json + diff -Nru libcpanel-json-xs-perl-3.0225/t/30_jsonspec.t libcpanel-json-xs-perl-3.0239/t/30_jsonspec.t --- libcpanel-json-xs-perl-3.0225/t/30_jsonspec.t 2016-11-16 11:34:01.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/30_jsonspec.t 2017-07-27 20:15:44.000000000 +0000 @@ -1,9 +1,9 @@ # regressions and differences from the JSON Specs and JSON::PP # detected by http://seriot.ch/json/parsing.html -use Test::More tests => 686; +use Test::More ($] >= 5.008) ? (tests => 686) : (skip_all => "needs 5.8"); use Cpanel::JSON::XS; BEGIN { - require Encode if $] < 5.020; # Currently required for <5.20 + require Encode if $] >= 5.008 && $] < 5.020; # Currently required for <5.20 } my $json = Cpanel::JSON::XS->new->utf8->allow_nonref; my $relaxed = Cpanel::JSON::XS->new->utf8->allow_nonref->relaxed; @@ -14,7 +14,7 @@ # i_string_unicode_*_nonchar ["\uDBFF\uDFFE"] (add warning as in core) # i_string_not_in_unicode_range Code point 0x13FFFF is not Unicode UTF8_DISALLOW_SUPER # y_string_utf16, y_string_utf16be, y_string_utf32, y_string_utf32be fixed with 3.0222 -my %todo = {}; +my %todo; $todo{'y_string_nonCharacterInUTF-8_U+FFFF'}++ if $] < 5.013; $todo{'n_string_UTF8_surrogate_U+D800'}++ if $] >= 5.012; if ($] < 5.008) { @@ -54,6 +54,8 @@ i_string_UTF-16_invalid_surrogate i_string_UTF-8_invalid_sequence i_string_not_in_unicode_range + y_object_duplicated_key + y_object_duplicated_key_and_value ); # should parse and return undef: my %i_empty = map{$_ => 1} @@ -166,7 +168,11 @@ close $fh; } my ($base) = ($f =~ m|test_parsing/(.*)\.json|); - if ($base =~ /^y_/) { + # This is arguably a specification bug. it should error on default + if ($base =~ /y_object_duplicated_key/) { + n_error($s, $base); + } + elsif ($base =~ /^y_/) { y_pass($s, $base); } elsif ($base =~ /^n_/) { diff -Nru libcpanel-json-xs-perl-3.0225/t/31_bom.t libcpanel-json-xs-perl-3.0239/t/31_bom.t --- libcpanel-json-xs-perl-3.0225/t/31_bom.t 2016-10-30 15:03:07.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/31_bom.t 2017-07-27 20:15:44.000000000 +0000 @@ -2,7 +2,7 @@ # # https://tools.ietf.org/html/rfc7159#section-8.1 # JSON text SHALL be encoded in UTF-8, UTF-16, or UTF-32. -use Test::More tests => 5; +use Test::More ($] >= 5.008) ? (tests => 5) : (skip_all => "needs 5.8");; use Cpanel::JSON::XS; use Encode; # Currently required for <5.20 use utf8; diff -Nru libcpanel-json-xs-perl-3.0225/t/96_interop_pp.t libcpanel-json-xs-perl-3.0239/t/96_interop_pp.t --- libcpanel-json-xs-perl-3.0225/t/96_interop_pp.t 1970-01-01 00:00:00.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/96_interop_pp.t 2017-07-27 20:15:44.000000000 +0000 @@ -0,0 +1,41 @@ +use Test::More; +BEGIN { + # for cperl CORE + eval "require JSON::PP;"; + if ($@) { + plan skip_all => "JSON::PP required for testing interop_pp"; + exit 0; + } else { + plan tests => 3; + } + $ENV{PERL_JSON_BACKEND} = 0; +} + +use JSON::PP (); # limitation: for interop with JSON load JSON::PP before Cpanel::JSON::XS +use Cpanel::JSON::XS (); + +my $cjson = Cpanel::JSON::XS->new; +my $boolstring = q({"is_true":true}); +my $js; +{ + local $ENV{PERL_JSON_BACKEND} = 'JSON::PP'; + my $json = JSON::PP->new; + $js = $json->decode( $boolstring ); + # bless { is_true => 1 }, "JSON::PP::Boolean" +} + +is ($cjson->encode( $js ), $boolstring) or diag "\$JSON::VERSION=$JSON::VERSION"; + +{ + local $ENV{PERL_JSON_BACKEND} = 'Cpanel::JSON::XS'; + my $json = JSON::PP->new; + $js = $json->decode( $boolstring ); + # bless { is_true => 1}, "Types::Serialiser" +} + +is($cjson->encode( $js ), $boolstring) + or diag "\$JSON::PP::VERSION=$JSON::PP::VERSION"; + +$js = $cjson->decode( $boolstring ); +is ($cjson->encode( $js ), $boolstring) or diag(ref $js->{is_true}); + diff -Nru libcpanel-json-xs-perl-3.0225/t/96_mojo.t libcpanel-json-xs-perl-3.0239/t/96_mojo.t --- libcpanel-json-xs-perl-3.0225/t/96_mojo.t 2016-06-06 13:26:10.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/96_mojo.t 2017-07-27 20:15:44.000000000 +0000 @@ -38,10 +38,15 @@ # fragile ok( $js->[0] eq '' or $js->[0] == 0 or !$js->[0], 'can decode Mojo false' ); is( $js->[1], 1, 'can decode Mojo true' ); -TODO: { - # Note this is fragile. it depends on the internal representation of booleans. - # It can also be ['0', '1'] - local $TODO = 'fragile'; +# Note this is fragile. it depends on the internal representation of booleans. +# It can also be ['0', '1'] +if ($js->[0] eq '') { is_deeply( $js, ['', 1], 'can decode Mojo booleans' ) or diag( $mj, $js ); +} else { + TODO: { + local $TODO = 'fragile false => "0"'; + is_deeply( $js, ['', 1], 'can decode Mojo booleans' ) + or diag( $mj, $js ); + } } diff -Nru libcpanel-json-xs-perl-3.0225/t/appveyor-test.bat libcpanel-json-xs-perl-3.0239/t/appveyor-test.bat --- libcpanel-json-xs-perl-3.0225/t/appveyor-test.bat 1970-01-01 00:00:00.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/appveyor-test.bat 2017-07-27 20:15:44.000000000 +0000 @@ -0,0 +1,41 @@ +@echo off + +rem Test::MinimumVersion JSON +set REQS=Pod::Text Time::Piece common::sense Mojo::JSON Test::LeakTrace Test::CPAN::Meta Test::Pod Test::Pod::Coverage +set PERL_MM_USE_DEFAULT=1 + +if not "%PLATFORM%" == "x64" set WIN64=undef +if "%STRAWBERRY%" == "1" goto gcc +if "%MSVC_CPERL%" == "1" goto msvc + +:gcc + +set PATH=C:\strawberry\perl\bin;C:\strawberry\perl\site\bin;C:\strawberry\c\bin;%PATH% +echo cpan -T %REQS% +call cpan -T %REQS% || exit /b 1 +echo perl Makefile.PL +perl Makefile.PL || exit /b 1 +rem strawberry switched with 5.26 from dmake to gmake +echo $Config{make} +perl -MConfig -e "system({$Config{make}} $Config{make}); exit(($? < 0 || $? & 127) ? 1 : ($? >> 8));" || exit /b 1 +echo $Config{make} test +perl -MConfig -e "system({$Config{make}} $Config{make}, 'test'); exit(($? < 0 || $? & 127) ? 1 : ($? >> 8));" || exit /b 1 + +exit /b + +:msvc +if "%PLATFORM%" == "x64" set PLATFORM=amd64 +rem 14 deviates from cperl with linker errors for the libc runtime +set MSVC_VERSION=12 +call "C:\Program Files (x86)\Microsoft Visual Studio %MSVC_VERSION%.0\VC\vcvarsall.bat" %PLATFORM% || exit /b 1 + +set PATH=C:\cperl\bin;C:\cperl\site\bin;%PATH% +echo cperl -S cpan -T %REQS% +cperl -S cpan -T %REQS% || exit /b 1 +echo cperl Makefile.PL +cperl Makefile.PL || exit /b 1 +echo nmake +nmake || exit /b 1 +echo nmake test +nmake test || exit /b 1 + diff -Nru libcpanel-json-xs-perl-3.0225/t/z_perl_minimum_version.t libcpanel-json-xs-perl-3.0239/t/z_perl_minimum_version.t --- libcpanel-json-xs-perl-3.0225/t/z_perl_minimum_version.t 2015-10-23 09:00:11.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/z_perl_minimum_version.t 2017-07-27 20:15:44.000000000 +0000 @@ -9,7 +9,7 @@ my @MODULES = ( 'Perl::MinimumVersion 1.20', - 'Test::MinimumVersion 0.008', + 'Test::MinimumVersion 0.101082', ); # Don't run tests during end-user installs diff -Nru libcpanel-json-xs-perl-3.0225/t/z_pod-spelling.t libcpanel-json-xs-perl-3.0239/t/z_pod-spelling.t --- libcpanel-json-xs-perl-3.0225/t/z_pod-spelling.t 2016-10-30 12:27:46.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/t/z_pod-spelling.t 2017-03-29 09:51:37.000000000 +0000 @@ -13,76 +13,117 @@ all_pod_files_spelling_ok(); __DATA__ -CBOR -cbor -syck -interop -nonref -noncharacters -Lehmann -bencode -clzf -commandline -fromformat -le -toformat -yaml -BOM BMP +BOM +BOM's BSON +CBOR CVE -Crockford Cpanel +Crockford +Crockford's +DESERIALIZATION +Deserializing ECMAscript GPL +IETF Iceweasel +JSON +JSON's KOI Lehmann +Lehmann MLEHMANN Mojo +MongoDB MovableType NOK +NaN's +OO +QNAN Reini +SNAN +STDIN +STDOUT SixApart Storable TCP +UTF XSS amd +arg +arrayrefs ascii autodetection backported backrefs +bencode +bugtracker cPanel +cbor +classname +clzf +codepoints codeset codesets +commandline conformant +cpan datastructure +deserialization +deserialize +deserialized deserializer +deserializing +fromformat +github +hashrefs +interop +interoperability ithread ithreads +javascript +javascript's +json latin +le nan +nd ness +noncharacters +nonref numifying onwards optimizations parsable +parsers postprocessing ppport -queryable -QNAN qnan +queryable +recurses recursing +repo resizes roundtripping +runtime sanify -SNAN +serializer +serializers snan src +storable +stringifies +stringifying superset +syck testsuite th +toformat typeless un +unblessed unicode +utf xs +yaml diff -Nru libcpanel-json-xs-perl-3.0225/.travis.yml libcpanel-json-xs-perl-3.0239/.travis.yml --- libcpanel-json-xs-perl-3.0225/.travis.yml 2016-10-30 12:27:46.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/.travis.yml 2017-07-29 15:18:21.000000000 +0000 @@ -11,12 +11,13 @@ - "5.20" - "5.22" - "5.24" - - "5.24-thr" - - "5.24-dbg" - - "5.24-thr-dbg" - - "5.24-mb" + - "5.26" + #- "5.26-thr" + #- "5.26-dbg" + #- "5.26-thr-dbg" + #- "5.26-mb" - "dev" - - "blead" +# - "blead" # slows down already cached versions by 3 (33s => 1m45s) # (i.e. cache download: 9s, setup: 45s-130s) @@ -26,10 +27,10 @@ # directories: # - /home/travis/perl5/perlbrew/ -#addons: -# apt: -# packages: -# - gperf +addons: + apt: + packages: + - aspell # blead and 5.6 stumble over YAML and more missing dependencies # for Devel::Cover::Report::Coveralls @@ -39,9 +40,12 @@ - ln -s `which true` /home/travis/bin/cpansign - eval $(curl https://travis-perl.github.io/init) --auto install: - - export AUTOMATED_TESTING=1 HARNESS_TIMER=1 AUTHOR_TESTING=0 RELEASE_TESTING=0 + - export AUTOMATED_TESTING=1 HARNESS_TIMER=1 - cpan-install --deps # installs prereqs, including recommends - cpan-install JSON JSON::PP JSON::XS Mojo::JSON Test::LeakTrace Time::Piece + - test x$AUTHOR_TESTING = x1 && cpan-install Test::CPAN::Meta Test::MinimumVersion + Pod::Spell::CommonMistakes Class::XSAccessor Test::Kwalitee Test::Spelling + Text::CSV_XS Test::Pod Test::Pod::Coverage - cpan-install --coverage # installs converage prereqs, if enabled before_script: diff -Nru libcpanel-json-xs-perl-3.0225/XS.pm libcpanel-json-xs-perl-3.0239/XS.pm --- libcpanel-json-xs-perl-3.0225/XS.pm 2016-11-23 18:25:00.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/XS.pm 2017-08-28 18:55:10.000000000 +0000 @@ -1,7 +1,7 @@ package Cpanel::JSON::XS; -our $VERSION = '3.0225'; +our $VERSION = '3.0239'; our $XS_VERSION = $VERSION; -$VERSION = eval $VERSION; +# $VERSION = eval $VERSION; =pod @@ -112,16 +112,17 @@ - stricter decode_json() as documented. non-refs are disallowed. added a 2nd optional argument. decode() honors now allow_nonref. -- fixed encode of numbers for dual-vars. Different string representations - are preserved, but numbers with temporary strings which represent the same number - are here treated as numbers, not strings. Cpanel::JSON::XS is a bit slower, but - preserves numeric types better. - -- numbers ending with .0 stay numbers, are not converted to integers. [#63] - dual-vars which are represented as number not integer (42+"bar" != 5.8.9) - are now encoded as number (=> 42.0) because internally it's now a NOK type. - However !!1 which is wrongly encoded in 5.8 as "1"/1.0 is still represented - as integer. +- fixed encode of numbers for dual-vars. Different string + representations are preserved, but numbers with temporary strings + which represent the same number are here treated as numbers, not + strings. Cpanel::JSON::XS is a bit slower, but preserves numeric + types better. + +- numbers ending with .0 stay numbers, are not converted to + integers. [#63] dual-vars which are represented as number not + integer (42+"bar" != 5.8.9) are now encoded as number (=> 42.0) + because internally it's now a NOK type. However !!1 which is + wrongly encoded in 5.8 as "1"/1.0 is still represented as integer. - different handling of inf/nan. Default now to null, optionally with stringify_infnan() to "inf"/"nan". [#28, #32] @@ -129,14 +130,14 @@ - added C extension, non-JSON and non JSON parsable, allows C<\xNN> and C<\NNN> sequences. -- 5.6.2 support; sacrificing some utf8 features (assuming bytes all-over), - no multi-byte unicode characters with 5.6. +- 5.6.2 support; sacrificing some utf8 features (assuming bytes + all-over), no multi-byte unicode characters with 5.6. - interop for true/false overloading. JSON::XS, JSON::PP and Mojo::JSON representations for booleans are accepted and JSON::XS accepts Cpanel::JSON::XS booleans [#13, #37] - Fixed overloading of booleans. Cpanel::JSON::XS::true stringifies now - to true, not 1. + Fixed overloading of booleans. Cpanel::JSON::XS::true stringifies again + to "1", not "true", analog to all other JSON modules. - native boolean mapping of yes and no to true and false, as in YAML::XS. In perl C is yes, C is no. @@ -170,24 +171,28 @@ - #72 parsing of illegal unicode or non-unicode characters. + - #96 locale-insensitive numeric conversion + - public maintenance and bugtracker - use ppport.h, sanify XS.xs comment styles, harness C coding style -- common::sense is optional. When available it is not used in the published - production module, just during development and testing. +- common::sense is optional. When available it is not used in the + published production module, just during development and testing. -- extended testsuite, passes all http://seriot.ch/parsing_json.html tests. - In fact it is the only know JSON decoder which does so, while being the fastest. +- extended testsuite, passes all http://seriot.ch/parsing_json.html + tests. In fact it is the only know JSON decoder which does so, + while also being the fastest. - support many more options and methods from JSON::PP: stringify_infnan, allow_unknown, allow_stringify, allow_barekey, - encode_stringify, allow_bignum, allow_singlequote, sort_by (partially), - escape_slash, convert_blessed, ... - optional decode_json(, allow_nonref) arg + encode_stringify, allow_bignum, allow_singlequote, sort_by + (partially), escape_slash, convert_blessed, ... optional + decode_json(, allow_nonref) arg. + relaxed implements allow_dupkeys. -- support all 5 unicode BOM's: UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE, - encoding internally to UTF-8. +- support all 5 unicode BOM's: UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, + UTF-32BE, encoding internally to UTF-8. =cut @@ -197,7 +202,9 @@ sub to_json($@) { if ($] >= 5.008) { require Carp; - Carp::croak ("Cpanel::JSON::XS::to_json has been renamed to encode_json, either downgrade to pre-2.0 versions of Cpanel::JSON::XS or rename the call"); + Carp::croak ("Cpanel::JSON::XS::to_json has been renamed to encode_json,". + " either downgrade to pre-2.0 versions of Cpanel::JSON::XS or". + " rename the call"); } else { _to_json(@_); } @@ -206,7 +213,9 @@ sub from_json($@) { if ($] >= 5.008) { require Carp; - Carp::croak ("Cpanel::JSON::XS::from_json has been renamed to decode_json, either downgrade to pre-2.0 versions of Cpanel::JSON::XS or rename the call"); + Carp::croak ("Cpanel::JSON::XS::from_json has been renamed to decode_json,". + " either downgrade to pre-2.0 versions of Cpanel::JSON::XS or". + " rename the call"); } else { _from_json(@_); } @@ -235,9 +244,9 @@ =item $perl_scalar = decode_json $json_text [, $allow_nonref ] -The opposite of C: expects an UTF-8 (binary) string of an json reference -and tries to parse that as an UTF-8 encoded JSON text, returning the resulting -reference. Croaks on error. +The opposite of C: expects an UTF-8 (binary) string of an +json reference and tries to parse that as an UTF-8 encoded JSON text, +returning the resulting reference. Croaks on error. This function call is functionally identical to: @@ -249,18 +258,20 @@ 3.0116 and JSON::XS did not set allow_nonref but allowed them due to a bug in the decoder. -If the new optional $allow_nonref argument is set and not false, the allow_nonref -option will be set and the function will act is described as in the relaxed RFC 7159 -allowing all values such as objects, arrays, strings, numbers, "null", "true", and "false". +If the new optional $allow_nonref argument is set and not false, the +allow_nonref option will be set and the function will act is described +as in the relaxed RFC 7159 allowing all values such as objects, +arrays, strings, numbers, "null", "true", and "false". =item $is_boolean = Cpanel::JSON::XS::is_bool $scalar -Returns true if the passed scalar represents either C or -C, two constants that act like C<1> and C<0>, respectively -and are used to represent JSON C and C values in Perl. +Returns true if the passed scalar represents either C +or C, two constants that act like C<1> and C<0>, +respectively and are used to represent JSON C and C +values in Perl. -See MAPPING, below, for more information on how JSON values are mapped to -Perl. +See MAPPING, below, for more information on how JSON values are mapped +to Perl. =back @@ -294,27 +305,29 @@ =item 2. Perl does I associate an encoding with your strings. ... until you force it to, e.g. when matching it against a regex, or -printing the scalar to a file, in which case Perl either interprets your -string as locale-encoded text, octets/binary, or as Unicode, depending -on various settings. In no case is an encoding stored together with your -data, it is I that decides encoding, not any magical meta data. +printing the scalar to a file, in which case Perl either interprets +your string as locale-encoded text, octets/binary, or as Unicode, +depending on various settings. In no case is an encoding stored +together with your data, it is I that decides encoding, not any +magical meta data. =item 3. The internal utf-8 flag has no meaning with regards to the encoding of your string. -=item 4. A "Unicode String" is simply a string where each character can be -validly interpreted as a Unicode code point. +=item 4. A "Unicode String" is simply a string where each character +can be validly interpreted as a Unicode code point. -If you have UTF-8 encoded data, it is no longer a Unicode string, but a -Unicode string encoded in UTF-8, giving you a binary string. +If you have UTF-8 encoded data, it is no longer a Unicode string, but +a Unicode string encoded in UTF-8, giving you a binary string. -=item 5. A string containing "high" (> 255) character values is I a UTF-8 string. +=item 5. A string containing "high" (> 255) character values is I +a UTF-8 string. =item 6. Unicode noncharacters only warn, as in core. -The 66 Unicode noncharacters U+FDD0..U+FDEF, and U+*FFFE, U+*FFFF just warn, -see L. -But illegal surrogate pairs fail to parse. +The 66 Unicode noncharacters U+FDD0..U+FDEF, and U+*FFFE, U+*FFFF just +warn, see L. But +illegal surrogate pairs fail to parse. =item 7. Raw non-Unicode characters above U+10FFFF are disallowed. @@ -409,9 +422,9 @@ If the C<$enable> argument is true (or missing), then the C method will not try to detect an UTF-8 encoding in any JSON string, it will strictly interpret it as byte sequence. The result might contain -new C<\xNN> sequences, which is B. The C method -forbids C<\uNNNN> sequences and accepts C<\xNN> and octal C<\NNN> -sequences. +new C<\xNN> sequences, which is B. The C +method forbids C<\uNNNN> sequences and accepts C<\xNN> and octal +C<\NNN> sequences. There is also a special logic for perl 5.6 and utf8. 5.6 encodes any string to utf-8 automatically when seeing a codepoint >= C<0x80> and @@ -506,9 +519,9 @@ =item $enabled = $json->get_indent -If C<$enable> is true (or missing), then the C method will use a multiline -format as output, putting every array member or object/hash key-value pair -into its own line, indenting them properly. +If C<$enable> is true (or missing), then the C method will use +a multiline format as output, putting every array member or +object/hash key-value pair into its own line, indenting them properly. If C<$enable> is false, no newlines or indenting will be produced, and the resulting JSON text is guaranteed not to contain any C. @@ -537,10 +550,10 @@ =item $enabled = $json->get_space_after -If C<$enable> is true (or missing), then the C method will add an extra -optional space after the C<:> separating keys from values in JSON objects -and extra whitespace after the C<,> separating key-value pairs and array -members. +If C<$enable> is true (or missing), then the C method will add +an extra optional space after the C<:> separating keys from values in +JSON objects and extra whitespace after the C<,> separating key-value +pairs and array members. If C<$enable> is false, then the C method will not add any extra space at those places. @@ -623,6 +636,12 @@ { foo:"bar" } +=item * duplicate keys + +With relaxed decoding of duplicate keys does not error and are silently accepted. +See L: +RFC 7159 section 4: "The names within an object should be unique." + =back @@ -630,8 +649,9 @@ =item $enabled = $json->get_canonical -If C<$enable> is true (or missing), then the C method will output JSON objects -by sorting their keys. This is adding a comparatively high overhead. +If C<$enable> is true (or missing), then the C method will +output JSON objects by sorting their keys. This is adding a +comparatively high overhead. If C<$enable> is false, then the C method will output key-value pairs in the order Perl stores them (which will likely change between runs @@ -705,7 +725,6 @@ $json->allow_barekey->decode('{foo:"bar"}'); - =item $json = $json->allow_bignum ([$enable]) =item $enabled = $json->get_allow_bignum @@ -716,8 +735,9 @@ the big integer Perl cannot handle as integer into a L object and convert a floating number (any) into a L. -On the contrary, C converts C objects and C -objects into JSON numbers with C enable. +On the contrary, C converts C objects and +C objects into JSON numbers with C +enable. $json->allow_nonref->allow_blessed->allow_bignum; $bigfloat = $json->decode('2.000000000000000000000000001'); @@ -736,10 +756,10 @@ =item $enabled = $json->get_allow_nonref -If C<$enable> is true (or missing), then the C method can convert a -non-reference into its corresponding string, number or null JSON value, -which is an extension to RFC4627. Likewise, C will accept those JSON -values instead of croaking. +If C<$enable> is true (or missing), then the C method can +convert a non-reference into its corresponding string, number or null +JSON value, which is an extension to RFC4627. Likewise, C will +accept those JSON values instead of croaking. If C<$enable> is false, then the C method will croak if it isn't passed an arrayref or hashref, as JSON texts must either be an object @@ -1001,21 +1021,21 @@ Stringified via sprintf(%g), with double quotes. inf/nan: infnan_mode = 2. As in JSON::XS, and older releases. -Passes through platform dependent values, invalid JSON. Stringified via sprintf(%g), -but without double quotes. +Passes through platform dependent values, invalid JSON. Stringified via +sprintf(%g), but without double quotes. -"inf/-inf/nan": infnan_mode = 3. Platform independent inf/nan/-inf strings. -No QNAN/SNAN/negative NAN support, unified to "nan". Much easier to detect, but may -conflict with valid strings. +"inf/-inf/nan": infnan_mode = 3. Platform independent inf/nan/-inf +strings. No QNAN/SNAN/negative NAN support, unified to "nan". Much +easier to detect, but may conflict with valid strings. =item $json_text = $json->encode ($perl_scalar) Converts the given Perl data structure (a simple scalar or a reference to a hash or array) to its JSON representation. Simple scalars will be -converted into JSON string or number sequences, while references to arrays -become JSON arrays and references to hashes become JSON objects. Undefined -Perl values (e.g. C) become JSON C values. Neither C -nor C values will be generated. +converted into JSON string or number sequences, while references to +arrays become JSON arrays and references to hashes become JSON +objects. Undefined Perl values (e.g. C) become JSON C +values. Neither C nor C values will be generated. =item $perl_scalar = $json->decode ($json_text) @@ -1061,14 +1081,14 @@ is much more efficient (and can be implemented with a minimum of method calls). -Cpanel::JSON::XS will only attempt to parse the JSON text once it is sure it -has enough text to get a decisive result, using a very simple but -truly incremental parser. This means that it sometimes won't stop as -early as the full parser, for example, it doesn't detect mismatched -parentheses. The only thing it guarantees is that it starts decoding as -soon as a syntactically valid JSON text has been seen. This means you need -to set resource limits (e.g. C) to ensure the parser will stop -parsing in the presence if syntax errors. +Cpanel::JSON::XS will only attempt to parse the JSON text once it is +sure it has enough text to get a decisive result, using a very simple +but truly incremental parser. This means that it sometimes won't stop +as early as the full parser, for example, it doesn't detect mismatched +parentheses. The only thing it guarantees is that it starts decoding +as soon as a syntactically valid JSON text has been seen. This means +you need to set resource limits (e.g. C) to ensure the +parser will stop parsing in the presence if syntax errors. The following methods implement this incremental parser. @@ -1148,15 +1168,16 @@ =head2 LIMITATIONS All options that affect decoding are supported, except -C. The reason for this is that it cannot be made to -work sensibly: JSON objects and arrays are self-delimited, i.e. you can concatenate -them back to back and still decode them perfectly. This does not hold true -for JSON numbers, however. - -For example, is the string C<1> a single JSON number, or is it simply the -start of C<12>? Or is C<12> a single JSON number, or the concatenation -of C<1> and C<2>? In neither case you can tell, and this is why Cpanel::JSON::XS -takes the conservative route and disallows this case. +C. The reason for this is that it cannot be made to work +sensibly: JSON objects and arrays are self-delimited, i.e. you can +concatenate them back to back and still decode them perfectly. This +does not hold true for JSON numbers, however. + +For example, is the string C<1> a single JSON number, or is it simply +the start of C<12>? Or is C<12> a single JSON number, or the +concatenation of C<1> and C<2>? In neither case you can tell, and this +is why Cpanel::JSON::XS takes the conservative route and disallows +this case. =head2 EXAMPLES @@ -1222,11 +1243,11 @@ but you cannot load it into memory fully (this has actually happened in the real world :). -Well, you lost, you have to implement your own JSON parser. But Cpanel::JSON::XS -can still help you: You implement a (very simple) array parser and let -JSON decode the array elements, which are all full JSON objects on their -own (this wouldn't work if the array elements could be JSON numbers, for -example): +Well, you lost, you have to implement your own JSON parser. But +Cpanel::JSON::XS can still help you: You implement a (very simple) +array parser and let JSON decode the array elements, which are all +full JSON objects on their own (this wouldn't work if the array +elements could be JSON numbers, for example): my $json = new Cpanel::JSON::XS; @@ -1312,15 +1333,15 @@ See also L. -Beware that Cpanel::JSON::XS is currently the only JSON module which does accept -and decode a BOM. +Beware that Cpanel::JSON::XS is currently the only JSON module which +does accept and decode a BOM. =head1 MAPPING -This section describes how Cpanel::JSON::XS maps Perl values to JSON values and -vice versa. These mappings are designed to "do the right thing" in most -circumstances automatically, preserving round-tripping characteristics -(what you put in comes out as something equivalent). +This section describes how Cpanel::JSON::XS maps Perl values to JSON +values and vice versa. These mappings are designed to "do the right +thing" in most circumstances automatically, preserving round-tripping +characteristics (what you put in comes out as something equivalent). For the more enlightened: note that in the following descriptions, lowercase I refers to the Perl interpreter, while uppercase I @@ -1354,12 +1375,12 @@ the conversion details, but an integer may take slightly less memory and might represent more values exactly than floating point numbers. -If the number consists of digits only, Cpanel::JSON::XS will try to represent -it as an integer value. If that fails, it will try to represent it as -a numeric (floating point) value if that is possible without loss of -precision. Otherwise it will preserve the number as a string value (in -which case you lose roundtripping ability, as the JSON number will be -re-encoded to a JSON string). +If the number consists of digits only, Cpanel::JSON::XS will try to +represent it as an integer value. If that fails, it will try to +represent it as a numeric (floating point) value if that is possible +without loss of precision. Otherwise it will preserve the number as a +string value (in which case you lose roundtripping ability, as the +JSON number will be re-encoded to a JSON string). Numbers containing a fractional or exponential part will always be represented as numeric (floating point) values, possibly at a loss of @@ -1454,7 +1475,7 @@ respectively. You can also use C<\1> and C<\0> or C and C directly if you want. - encode_json [Cpanel::JSON::XS::true, Cpanel::JSON::XS::true] # yields [false,true] + encode_json [Cpanel::JSON::XS::true, Cpanel::JSON::XS::true] # yields [false,true] encode_json [!1, !0] # yields [false,true] =item blessed objects @@ -1530,9 +1551,9 @@ =head3 SERIALIZATION -What happens when C encounters a Perl object depends on the -C, C and C settings, which are -used in this order: +What happens when C encounters a Perl object depends +on the C, C and C +settings, which are used in this order: =over 4 @@ -2178,7 +2199,7 @@ sub is_bool($) { shift if @_ == 2; # as method call (ref($_[0]) and UNIVERSAL::isa( $_[0], JSON::PP::Boolean::)) - or (exists $INC{'Types/Serializer.pm'} and Types::Serialiser::is_bool($_[0])) + or (exists $INC{'Types/Serialiser.pm'} and Types::Serialiser::is_bool($_[0])) } XSLoader::load 'Cpanel::JSON::XS', $XS_VERSION; @@ -2194,11 +2215,11 @@ "0+" => sub { ${$_[0]} }, "++" => sub { $_[0] = ${$_[0]} + 1 }, "--" => sub { $_[0] = ${$_[0]} - 1 }, - '""' => sub { ${$_[0]} == 1 ? 'true' : '0' }, # GH 29 + '""' => sub { ${$_[0]} == 1 ? '1' : '0' }, # GH 29 'eq' => sub { my ($obj, $op) = ref ($_[0]) ? ($_[0], $_[1]) : ($_[1], $_[0]); if ($op eq 'true' or $op eq 'false') { - return "$obj" eq 'true' ? 'true' eq $op : 'false' eq $op; + return "$obj" eq '1' ? 'true' eq $op : 'false' eq $op; } else { return $obj ? 1 == $op : 0 == $op; @@ -2227,11 +2248,11 @@ Marc Lehmann , http://home.schmorp.de/ -Reini Urban , http://cpanel.net/ +Reini Urban =head1 MAINTAINER -Reini Urban +Reini Urban =cut diff -Nru libcpanel-json-xs-perl-3.0225/XS.xs libcpanel-json-xs-perl-3.0239/XS.xs --- libcpanel-json-xs-perl-3.0225/XS.xs 2016-11-23 18:22:32.000000000 +0000 +++ libcpanel-json-xs-perl-3.0239/XS.xs 2017-08-28 18:55:10.000000000 +0000 @@ -28,6 +28,10 @@ #define HAVE_BAD_POWL #endif +#if PERL_VERSION < 22 && defined(HAS_SETLOCALE) +#define NEED_NUMERIC_LOCALE_C +#endif + /* FIXME: still a refcount error */ #define HAVE_DECODE_BOM #define UTF8BOM "\357\273\277" /* EF BB BF */ @@ -36,13 +40,19 @@ #define UTF32BOM "\377\376\000\000" /* FF FE 00 00 or +UFEFF */ #define UTF32BOM_BE "\000\000\376\377" /* 00 00 FE FF */ -/* strawberry 5.22 with USE_MINGW_ANSI_STDIO and USE_LONG_DOUBLE has now - a proper inf/nan */ +/* mingw with USE_LONG_DOUBLE (and implied USE_MINGW_ANSI_STDIO) do use the + non-msvcrt inf/nan stringification in sprintf(). */ #if defined(WIN32) && !defined(__USE_MINGW_ANSI_STDIO) && !defined(USE_LONG_DOUBLE) -#define STR_INF "1.#INF" -#define STR_INF2 "1.#INF.0" -#define STR_NAN "1.#IND" -#define STR_QNAN "1.#QNAN" +/* new ucrtd.dll runtime? We do not probe the runtime or variants in the Makefile.PL yet. */ +#define STR_INF "inf" +#define STR_INF2 "inf.0" +#define STR_NAN "nan" +#define STR_QNAN "nan(ind)" +/* old standard msvcrt.dll */ +#define STR_INF3 "1.#INF" +#define STR_INF4 "1.#INF.0" +#define STR_NAN2 "1.#IND" +#define STR_QNAN2 "1.#QNAN" #define HAVE_QNAN #elif defined(sun) || defined(__sun) #define STR_INF "Infinity" @@ -50,6 +60,7 @@ #elif defined(__hpux) #define STR_INF "++" #define STR_NAN "-?" +#define HAVE_NEG_NAN #define STR_NEG_INF "---" #define STR_NEG_NAN "?" #else @@ -226,11 +237,7 @@ #define SHORT_STRING_LEN 16384 // special-case strings of up to this size -#if PERL_VERSION >= 8 #define DECODE_WANTS_OCTETS(json) ((json)->flags & F_UTF8) -#else -#define DECODE_WANTS_OCTETS(json) (0) -#endif #define SB do { #define SE } while (0) @@ -243,8 +250,8 @@ # define INLINE static #endif #ifndef LIKELY -#define LIKELY(expr) _expect ((expr) != 0, 1) -#define UNLIKELY(expr) _expect ((expr) != 0, 0) +#define LIKELY(expr) _expect ((long)(expr) != 0, 1) +#define UNLIKELY(expr) _expect ((long)(expr) != 0, 0) #endif #define IN_RANGE_INC(type,val,beg,end) \ @@ -358,7 +365,8 @@ INLINE void shrink (pTHX_ SV *sv) { - sv_utf8_downgrade (sv, 1); + /* ignore errors */ + (void)sv_utf8_downgrade (sv, 1); if (SvLEN (sv) > SvCUR (sv) + 1) { @@ -474,13 +482,13 @@ return s; } -/* convert offset pointer to character index, sv must be string */ +/* convert offset to character index, sv must be string */ static STRLEN -ptr_to_index (pTHX_ SV *sv, const U8 *offset) +ptr_to_index (pTHX_ SV *sv, const STRLEN offset) { return SvUTF8 (sv) - ? utf8_distance ((U8*)offset, (U8*)SvPVX (sv)) - : offset - (U8*)SvPVX (sv); + ? (STRLEN)utf8_distance ((U8*)(SvPVX(sv)+offset), (U8*)SvPVX (sv)) + : offset; } /*/////////////////////////////////////////////////////////////////////////// */ @@ -681,6 +689,11 @@ INLINE void need (pTHX_ enc_t *enc, STRLEN len) { +#if PERL_VERSION > 6 + DEBUG_v(Perl_deb(aTHX_ "need enc: %p %p %4ld, want: %lu\n", enc->cur, enc->end, + (long)(enc->end - enc->cur), (unsigned long)len)); +#endif + assert(enc->cur <= enc->end); if (UNLIKELY(enc->cur + len >= enc->end)) { STRLEN cur = enc->cur - (char *)SvPVX (enc->sv); @@ -717,44 +730,59 @@ while (str < end) { unsigned char ch = *(unsigned char *)str; - +#if PERL_VERSION > 6 + DEBUG_v(Perl_deb(aTHX_ "str enc: %p %p %4ld, want: %lu\n", enc->cur, enc->end, + (long)(enc->end - enc->cur), (long unsigned)len)); +#endif if (LIKELY(ch >= 0x20 && ch < 0x80)) /* most common case */ { + assert(enc->cur <= enc->end); if (UNLIKELY(ch == '"')) /* but with slow exceptions */ { - need (aTHX_ enc, len += 1); + need (aTHX_ enc, 2); *enc->cur++ = '\\'; *enc->cur++ = '"'; + ++len; } else if (UNLIKELY(ch == '\\')) { - need (aTHX_ enc, len += 1); + need (aTHX_ enc, 2); *enc->cur++ = '\\'; *enc->cur++ = '\\'; + ++len; } else if (UNLIKELY(ch == '/' && (enc->json.flags & F_ESCAPE_SLASH))) { - need (aTHX_ enc, len += 1); + need (aTHX_ enc, 2); *enc->cur++ = '\\'; *enc->cur++ = '/'; + ++len; } - else + else { + need (aTHX_ enc, 1); *enc->cur++ = ch; + } ++str; } else { + assert(enc->cur <= enc->end); switch (ch) { - case '\010': need (aTHX_ enc, len += 1); *enc->cur++ = '\\'; *enc->cur++ = 'b'; ++str; break; - case '\011': need (aTHX_ enc, len += 1); *enc->cur++ = '\\'; *enc->cur++ = 't'; ++str; break; - case '\012': need (aTHX_ enc, len += 1); *enc->cur++ = '\\'; *enc->cur++ = 'n'; ++str; break; - case '\014': need (aTHX_ enc, len += 1); *enc->cur++ = '\\'; *enc->cur++ = 'f'; ++str; break; - case '\015': need (aTHX_ enc, len += 1); *enc->cur++ = '\\'; *enc->cur++ = 'r'; ++str; break; + case '\010': need (aTHX_ enc, 2); + *enc->cur++ = '\\'; *enc->cur++ = 'b'; ++len; ++str; break; + case '\011': need (aTHX_ enc, 2); + *enc->cur++ = '\\'; *enc->cur++ = 't'; ++len; ++str; break; + case '\012': need (aTHX_ enc, 2); + *enc->cur++ = '\\'; *enc->cur++ = 'n'; ++len; ++str; break; + case '\014': need (aTHX_ enc, 2); + *enc->cur++ = '\\'; *enc->cur++ = 'f'; ++len; ++str; break; + case '\015': need (aTHX_ enc, 2); + *enc->cur++ = '\\'; *enc->cur++ = 'r'; ++len; ++str; break; - default: - { + default: + { STRLEN clen; UV uch; @@ -776,49 +804,55 @@ if (enc->json.flags & F_BINARY) { /* MB cannot arrive here */ - need (aTHX_ enc, len += 3); + need (aTHX_ enc, 4); *enc->cur++ = '\\'; *enc->cur++ = 'x'; *enc->cur++ = PL_hexdigit [(uch >> 4) & 15]; *enc->cur++ = PL_hexdigit [ uch & 15]; + len += 3; } else if (uch >= 0x10000UL) { if (uch >= 0x110000UL) croak ("out of range codepoint (0x%lx) encountered, unrepresentable in JSON", (unsigned long)uch); - need (aTHX_ enc, len += 11); + need (aTHX_ enc, 12); sprintf (enc->cur, "\\u%04x\\u%04x", (int)((uch - 0x10000) / 0x400 + 0xD800), (int)((uch - 0x10000) % 0x400 + 0xDC00)); enc->cur += 12; + len += 11; } else { - need (aTHX_ enc, len += 5); + need (aTHX_ enc, 6); *enc->cur++ = '\\'; *enc->cur++ = 'u'; *enc->cur++ = PL_hexdigit [ uch >> 12 ]; *enc->cur++ = PL_hexdigit [(uch >> 8) & 15]; *enc->cur++ = PL_hexdigit [(uch >> 4) & 15]; *enc->cur++ = PL_hexdigit [ uch & 15]; + len += 5; } str += clen; } else if (enc->json.flags & F_LATIN1) { + need (aTHX_ enc, 1); *enc->cur++ = uch; str += clen; } else if (enc->json.flags & F_BINARY) { + need (aTHX_ enc, 1); *enc->cur++ = uch; str += clen; } else if (is_utf8) { - need (aTHX_ enc, len += clen); + need (aTHX_ enc, clen); + len += clen; do { *enc->cur++ = *str++; @@ -827,9 +861,10 @@ } else { /* never more than 11 bytes needed */ - need (aTHX_ enc, len += UTF8_MAXBYTES - 1); + need (aTHX_ enc, UTF8_MAXBYTES); enc->cur = (char*)encode_utf8 ((U8*)enc->cur, uch); ++str; + len += UTF8_MAXBYTES - 1; } } } @@ -861,7 +896,6 @@ INLINE void encode_space (pTHX_ enc_t *enc) { - need (aTHX_ enc, 1); encode_ch (aTHX_ enc, ' '); } @@ -870,7 +904,6 @@ { if (enc->json.flags & F_INDENT) { - need (aTHX_ enc, 1); encode_ch (aTHX_ enc, '\n'); } } @@ -1358,6 +1391,9 @@ { char *savecur, *saveend; char inf_or_nan = 0; +#ifdef NEED_NUMERIC_LOCALE_C + char *locale = NULL; +#endif NV nv = SvNVX(sv); /* trust that perl will do the right thing w.r.t. JSON syntax. */ need (aTHX_ enc, NV_DIG + 32); @@ -1372,9 +1408,16 @@ # else if (UNLIKELY(isinf(nv) || isnan(nv))) # endif - { - goto is_inf_or_nan; - } + { + goto is_inf_or_nan; + } + } +#endif + /* locale insensitive sprintf radix #96 */ +#ifdef NEED_NUMERIC_LOCALE_C + locale = setlocale(LC_NUMERIC, NULL); + if (!locale || strNE(locale, "C")) { + setlocale(LC_NUMERIC, "C"); } #endif #ifdef USE_QUADMATH @@ -1382,13 +1425,23 @@ #else (void)Gconvert (nv, NV_DIG, 0, enc->cur); #endif +#ifdef NEED_NUMERIC_LOCALE_C + if (locale) + setlocale(LC_NUMERIC, locale); +#endif +#ifdef STR_INF4 + if (UNLIKELY(strEQc(enc->cur, STR_INF) + || strEQc(enc->cur, STR_INF2) + || strEQc(enc->cur, STR_INF3) + || strEQc(enc->cur, STR_INF4))) +#elif defined(STR_INF2) + if (UNLIKELY(strEQc(enc->cur, STR_INF) + || strEQc(enc->cur, STR_INF2))) +#else if (UNLIKELY(strEQc(enc->cur, STR_INF))) - inf_or_nan = 1; -#ifdef STR_INF2 - else if (UNLIKELY(strEQc(enc->cur, STR_INF2))) - inf_or_nan = 1; #endif + inf_or_nan = 1; #if defined(__hpux) else if (UNLIKELY(strEQc(enc->cur, STR_NEG_INF))) inf_or_nan = 2; @@ -1397,23 +1450,43 @@ #endif else if #ifdef HAVE_QNAN +# ifdef STR_QNAN2 + (UNLIKELY(strEQc(enc->cur, STR_NAN) + || strEQc(enc->cur, STR_QNAN) + || strEQc(enc->cur, STR_NAN2) + || strEQc(enc->cur, STR_QNAN2))) +# else (UNLIKELY(strEQc(enc->cur, STR_NAN) || strEQc(enc->cur, STR_QNAN))) +# endif #else (UNLIKELY(strEQc(enc->cur, STR_NAN))) #endif inf_or_nan = 3; else if (*enc->cur == '-') { +#ifdef STR_INF4 + if (UNLIKELY(strEQc(enc->cur+1, STR_INF) + || strEQc(enc->cur+1, STR_INF2) + || strEQc(enc->cur+1, STR_INF3) + || strEQc(enc->cur+1, STR_INF4))) +#elif defined(STR_INF2) + if (UNLIKELY(strEQc(enc->cur+1, STR_INF) + || strEQc(enc->cur+1, STR_INF2))) +#else if (UNLIKELY(strEQc(enc->cur+1, STR_INF))) - inf_or_nan = 2; -#ifdef STR_INF2 - else if (UNLIKELY(strEQc(enc->cur+1, STR_INF2))) - inf_or_nan = 2; #endif + inf_or_nan = 2; else if #ifdef HAVE_QNAN +# ifdef STR_QNAN2 + (UNLIKELY(strEQc(enc->cur+1, STR_NAN) + || strEQc(enc->cur+1, STR_QNAN) + || strEQc(enc->cur+1, STR_NAN2) + || strEQc(enc->cur+1, STR_QNAN2))) +# else (UNLIKELY(strEQc(enc->cur+1, STR_NAN) || strEQc(enc->cur+1, STR_QNAN))) +# endif #else (UNLIKELY(strEQc(enc->cur+1, STR_NAN))) #endif @@ -1442,7 +1515,8 @@ strncpy(enc->cur, "\"nan\"\0", 6); } else if (enc->json.infnan_mode != 2) { - croak ("invalid stringify_infnan mode %c. Must be 0, 1, 2 or 3", enc->json.infnan_mode); + croak ("invalid stringify_infnan mode %c. Must be 0, 1, 2 or 3", + enc->json.infnan_mode); } } if (SvPOKp (sv) && !strEQ(enc->cur, SvPVX (sv))) { @@ -2670,6 +2744,7 @@ HV *hv = newHV (); int allow_squote = dec->json.flags & F_ALLOW_SQUOTE; int allow_barekey = dec->json.flags & F_ALLOW_BAREKEY; + int relaxed = dec->json.flags & F_RELAXED; char endstr = '"'; DEC_INC_DEPTH; @@ -2751,6 +2826,10 @@ if (UNLIKELY(p - key > I32_MAX)) ERR ("Hash key too large"); #endif + if (!relaxed && UNLIKELY(hv_exists (hv, key, len))) { + ERR ("Duplicate keys not allowed"); + } + dec->cur = p + 1; decode_ws (dec); if (*p != ':') EXPECT_CH (':'); @@ -2804,7 +2883,7 @@ { if (dec->json.cb_sk_object && HvKEYS (hv) == 1) { - HE *cb, *he; + HE *cb = NULL, *he; hv_iterinit (hv); he = hv_iternext (hv); @@ -2812,7 +2891,8 @@ /* the next line creates a mortal sv each time it's called. */ /* might want to optimise this for common cases. */ - cb = hv_fetch_ent (dec->json.cb_sk_object, hv_iterkeysv (he), 0, 0); + if (LIKELY((long)he)) + cb = hv_fetch_ent (dec->json.cb_sk_object, hv_iterkeysv (he), 0, 0); if (cb) { @@ -3068,18 +3148,19 @@ } static SV * -decode_json (pTHX_ SV *string, JSON *json, U8 **offset_return) +decode_json (pTHX_ SV *string, JSON *json, STRLEN *offset_return) { dec_t dec; SV *sv; STRLEN len, offset = 0; int converted = 0; - dMY_CXT; + /*dMY_CXT;*/ /* work around bugs in 5.10 where manipulating magic values * makes perl ignore the magic in subsequent accesses. * also make a copy of non-PV values, to get them into a clean * state (SvPV should do that, but it's buggy, see below). + * But breaks decode_prefix with offset. */ /*SvGETMAGIC (string);*/ if (SvMAGICAL (string) || !SvPOK (string) || SvIsCOW_shared_hash(string)) @@ -3148,14 +3229,12 @@ } } -#if PERL_VERSION >= 8 if (LIKELY(!converted)) { if (DECODE_WANTS_OCTETS (json)) sv_utf8_downgrade (string, 0); else sv_utf8_upgrade (string); } -#endif /* should basically be a NOP but needed for 5.6 with undef */ if (!SvPOK(string)) @@ -3175,8 +3254,12 @@ decode_ws (&dec); sv = decode_sv (aTHX_ &dec); - if (offset_return) - *offset_return = (U8*)dec.cur; + if (offset_return) { + if (dec.cur < SvPVX (string) || dec.cur > SvEND (string)) + *offset_return = 0; + else + *offset_return = dec.cur - SvPVX (string); + } if (!(offset_return || !sv)) { @@ -3213,7 +3296,7 @@ #endif croak ("%s, at character offset %d (before \"%s\")", dec.err, - (int)ptr_to_index (aTHX_ string, (U8*)dec.cur), + (int)ptr_to_index (aTHX_ string, dec.cur-SvPVX(string)), dec.cur != dec.end ? SvPV_nolen (uni) : "(end of string)"); } @@ -3407,7 +3490,7 @@ #ifdef USE_ITHREADS void CLONE (...) - CODE: + PPCODE: { MY_CXT_CLONE; /* possible declaration */ init_MY_CXT(aTHX_ &MY_CXT); @@ -3417,17 +3500,17 @@ #endif void END(...) - PREINIT: + PREINIT: dMY_CXT; SV * sv; - PPCODE: + PPCODE: sv = MY_CXT.sv_json; MY_CXT.sv_json = NULL; SvREFCNT_dec_NN(sv); return; /* skip implicit PUTBACK, returning @_ to caller, more efficient*/ void new (char *klass) - PPCODE: + PPCODE: { dMY_CXT; SV *pv = NEWSV (0, sizeof (JSON)); @@ -3440,7 +3523,7 @@ } void ascii (JSON *self, int enable = 1) - ALIAS: + ALIAS: ascii = F_ASCII latin1 = F_LATIN1 binary = F_BINARY @@ -3462,18 +3545,15 @@ allow_bignum = F_ALLOW_BIGNUM escape_slash = F_ESCAPE_SLASH allow_stringify = F_ALLOW_STRINGIFY - PPCODE: -{ + PPCODE: if (enable) self->flags |= ix; else self->flags &= ~ix; - XPUSHs (ST (0)); -} void get_ascii (JSON *self) - ALIAS: + ALIAS: get_ascii = F_ASCII get_latin1 = F_LATIN1 get_binary = F_BINARY @@ -3494,33 +3574,33 @@ get_allow_bignum = F_ALLOW_BIGNUM get_escape_slash = F_ESCAPE_SLASH get_allow_stringify = F_ALLOW_STRINGIFY - PPCODE: + PPCODE: XPUSHs (boolSV (self->flags & ix)); void max_depth (JSON *self, U32 max_depth = 0x80000000UL) - PPCODE: + PPCODE: self->max_depth = max_depth; XPUSHs (ST (0)); U32 get_max_depth (JSON *self) - CODE: + CODE: RETVAL = self->max_depth; - OUTPUT: + OUTPUT: RETVAL void max_size (JSON *self, U32 max_size = 0) - PPCODE: + PPCODE: self->max_size = max_size; XPUSHs (ST (0)); int get_max_size (JSON *self) - CODE: + CODE: RETVAL = self->max_size; - OUTPUT: + OUTPUT: RETVAL void stringify_infnan (JSON *self, IV infnan_mode = 1) - PPCODE: + PPCODE: if (infnan_mode > 3 || infnan_mode < 0) { croak ("invalid stringify_infnan mode %d. Must be 0, 1, 2 or 3", (int)infnan_mode); } @@ -3528,13 +3608,13 @@ XPUSHs (ST (0)); int get_stringify_infnan (JSON *self) - CODE: + CODE: RETVAL = (int)self->infnan_mode; - OUTPUT: + OUTPUT: RETVAL void sort_by (JSON *self, SV* cb = &PL_sv_yes) - PPCODE: + PPCODE: { SvREFCNT_dec (self->cb_sort_by); self->cb_sort_by = SvOK (cb) ? newSVsv (cb) : 0; @@ -3546,7 +3626,7 @@ void filter_json_object (JSON *self, SV *cb = &PL_sv_undef) - PPCODE: + PPCODE: { SvREFCNT_dec (self->cb_object); self->cb_object = SvOK (cb) ? newSVsv (cb) : 0; @@ -3555,16 +3635,16 @@ } void filter_json_single_key_object (JSON *self, SV *key, SV *cb = &PL_sv_undef) - PPCODE: + PPCODE: { if (!self->cb_sk_object) self->cb_sk_object = newHV (); if (SvOK (cb)) - hv_store_ent (self->cb_sk_object, key, newSVsv (cb), 0); + (void)hv_store_ent (self->cb_sk_object, key, newSVsv (cb), 0); else { - hv_delete_ent (self->cb_sk_object, key, G_DISCARD, 0); + (void)hv_delete_ent (self->cb_sk_object, key, G_DISCARD, 0); if (!HvKEYS (self->cb_sk_object)) { @@ -3577,20 +3657,20 @@ } void encode (JSON *self, SV *scalar) - PPCODE: + PPCODE: PUTBACK; scalar = encode_json (aTHX_ scalar, self); SPAGAIN; XPUSHs (scalar); void decode (JSON *self, SV *jsonstr) - PPCODE: + PPCODE: PUTBACK; jsonstr = decode_json (aTHX_ jsonstr, self, 0); SPAGAIN; XPUSHs (jsonstr); void decode_prefix (JSON *self, SV *jsonstr) - PPCODE: + PPCODE: { SV *sv; - U8 *offset; + STRLEN offset; PUTBACK; sv = decode_json (aTHX_ jsonstr, self, &offset); SPAGAIN; EXTEND (SP, 2); PUSHs (sv); @@ -3598,7 +3678,7 @@ } void incr_parse (JSON *self, SV *jsonstr = 0) - PPCODE: + PPCODE: { if (!self->incr_text) self->incr_text = newSVpvn ("", 0); @@ -3653,7 +3733,8 @@ do { SV *sv; - U8 *offset; + STRLEN offset; + char *endp; if (!INCR_DONE (self)) { @@ -3679,13 +3760,14 @@ PUTBACK; sv = decode_json (aTHX_ self->incr_text, self, &offset); SPAGAIN; XPUSHs (sv); - self->incr_pos -= offset - (U8*)SvPVX (self->incr_text); + endp = SvPVX(self->incr_text) + offset; + self->incr_pos -= offset; self->incr_nest = 0; self->incr_mode = 0; #if PERL_VERSION > 9 - sv_chop (self->incr_text, (const char* const)offset); + sv_chop (self->incr_text, (const char* const)endp); #else - sv_chop (self->incr_text, (char*)offset); + sv_chop (self->incr_text, (char*)endp); #endif } while (GIMME_V == G_ARRAY); @@ -3694,21 +3776,21 @@ #if PERL_VERSION > 6 SV *incr_text (JSON *self) - ATTRS: lvalue - CODE: + ATTRS: lvalue + CODE: { if (UNLIKELY(self->incr_pos)) croak ("incr_text can not be called when the incremental parser already started parsing"); RETVAL = self->incr_text ? SvREFCNT_inc (self->incr_text) : &PL_sv_undef; } - OUTPUT: + OUTPUT: RETVAL #else SV *incr_text (JSON *self) - CODE: + CODE: { if (UNLIKELY(self->incr_pos)) croak ("incr_text can not be called when the incremental parser already started parsing");