Hello community,

here is the log from the commit of package perl-Cpanel-JSON-XS for 
openSUSE:Factory checked in at 2019-10-21 12:29:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Cpanel-JSON-XS (Old)
 and      /work/SRC/openSUSE:Factory/.perl-Cpanel-JSON-XS.new.2352 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-Cpanel-JSON-XS"

Mon Oct 21 12:29:57 2019 rev:21 rq:741228 version:4.14

Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-Cpanel-JSON-XS/perl-Cpanel-JSON-XS.changes  
2019-09-26 20:37:41.471110466 +0200
+++ 
/work/SRC/openSUSE:Factory/.perl-Cpanel-JSON-XS.new.2352/perl-Cpanel-JSON-XS.changes
        2019-10-21 12:29:57.488066628 +0200
@@ -1,0 +2,20 @@
+Wed Oct 16 10:10:00 UTC 2019 -  <[email protected]>
+
+- updated to 4.14
+   see /usr/share/doc/packages/perl-Cpanel-JSON-XS/Changes
+
+  4.14 2019-10-15 (rurban)
+          - Fix tests for nvtype long double (#153)
+          - Fix PREREQ's. E.g. CentOS 7 has not Test::More anymore. (#152 by 
Pali)
+  
+  4.13 2019-10-14 (rurban)
+          - For JSON_TYPE_INT and JSON_TYPE_FLOAT allow to encode numeric 
values
+            above 2^64 in PV slot via Math::BigInt/Float (#145, #148, #149 by 
Pali)
+          - For JSON_TYPE_INT and JSON_TYPE_FLOAT encoder allow to pass 
Math::BigInt
+            and Math::BigFloat objects with allow_bignum. (#147 by Pali)
+          - Fix encoding floating point values above 2^64 in PV slot to 
JSON_TYPE_INT
+            (#148, #150 by Pali)
+          - Do not allow serializing objects when convert_blessed is not 
enabled.
+            (#146 by Pali)
+
+-------------------------------------------------------------------

Old:
----
  Cpanel-JSON-XS-4.12.tar.gz

New:
----
  Cpanel-JSON-XS-4.14.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ perl-Cpanel-JSON-XS.spec ++++++
--- /var/tmp/diff_new_pack.NWar6T/_old  2019-10-21 12:29:58.168067399 +0200
+++ /var/tmp/diff_new_pack.NWar6T/_new  2019-10-21 12:29:58.188067421 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           perl-Cpanel-JSON-XS
-Version:        4.12
+Version:        4.14
 Release:        0
 %define cpan_name Cpanel-JSON-XS
 Summary:        CPanel fork of JSON::XS, fast and correct serializing

++++++ Cpanel-JSON-XS-4.12.tar.gz -> Cpanel-JSON-XS-4.14.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.12/.travis.yml 
new/Cpanel-JSON-XS-4.14/.travis.yml
--- old/Cpanel-JSON-XS-4.12/.travis.yml 2019-06-10 17:04:29.000000000 +0200
+++ new/Cpanel-JSON-XS-4.14/.travis.yml 2019-09-24 14:44:58.000000000 +0200
@@ -80,6 +80,8 @@
     - env: COVERAGE=1 AUTHOR_TESTING=1
     - perl: "blead"
     - perl: "5.6.2" # cp5.6.2an.barnyard.co.uk sometimes down
+    - perl: "5.28"
+      env: cperl=cperl-5.28.2
 
 # Hack to not run on tag pushes:
 branches:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.12/Changes 
new/Cpanel-JSON-XS-4.14/Changes
--- old/Cpanel-JSON-XS-4.12/Changes     2019-06-11 09:24:57.000000000 +0200
+++ new/Cpanel-JSON-XS-4.14/Changes     2019-10-15 16:55:27.000000000 +0200
@@ -2,6 +2,20 @@
 
 TODO: http://stevehanov.ca/blog/index.php?id=104 compression
 
+4.14 2019-10-15 (rurban)
+        - Fix tests for nvtype long double (#153)
+        - Fix PREREQ's. E.g. CentOS 7 has not Test::More anymore. (#152 by 
Pali)
+
+4.13 2019-10-14 (rurban)
+        - For JSON_TYPE_INT and JSON_TYPE_FLOAT allow to encode numeric values
+          above 2^64 in PV slot via Math::BigInt/Float (#145, #148, #149 by 
Pali)
+        - For JSON_TYPE_INT and JSON_TYPE_FLOAT encoder allow to pass 
Math::BigInt
+          and Math::BigFloat objects with allow_bignum. (#147 by Pali)
+        - Fix encoding floating point values above 2^64 in PV slot to 
JSON_TYPE_INT
+          (#148, #150 by Pali)
+        - Do not allow serializing objects when convert_blessed is not enabled.
+          (#146 by Pali)
+
 4.12 2019-06-11 (rurban)
         - Make encoder independent on Math::BigInt version (#140 by Pali)
         - Rethrow error from eval_sv and eval_pv() (#138, #139 by Pali),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.12/META.json 
new/Cpanel-JSON-XS-4.14/META.json
--- old/Cpanel-JSON-XS-4.12/META.json   2019-06-11 10:02:48.000000000 +0200
+++ new/Cpanel-JSON-XS-4.14/META.json   2019-10-15 17:15:06.000000000 +0200
@@ -4,7 +4,7 @@
       "Reini Urban <[email protected]>"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "ExtUtils::MakeMaker version 7.36, CPAN::Meta::Converter 
version 2.150010",
+   "generated_by" : "ExtUtils::MakeMaker version 8.3508, CPAN::Meta::Converter 
version 2.150010",
    "license" : [
       "perl_5"
    ],
@@ -27,12 +27,36 @@
       },
       "configure" : {
          "requires" : {
+            "Config" : "0",
             "ExtUtils::MakeMaker" : "0"
          }
       },
       "runtime" : {
          "requires" : {
-            "Pod::Text" : "2.08"
+            "Carp" : "0",
+            "Encode" : "1.9801",
+            "Exporter" : "0",
+            "Pod::Text" : "2.08",
+            "XSLoader" : "0",
+            "overload" : "0",
+            "strict" : "0",
+            "warnings" : "0"
+         }
+      },
+      "test" : {
+         "requires" : {
+            "B" : "0",
+            "Config" : "0",
+            "Data::Dumper" : "0",
+            "Devel::Peek" : "0",
+            "POSIX" : "0",
+            "Test" : "0",
+            "Test::More" : "0",
+            "Tie::Array" : "0",
+            "Tie::Hash" : "0",
+            "charnames" : "0",
+            "lib" : "0",
+            "utf8" : "0"
          }
       }
    },
@@ -48,7 +72,7 @@
          "url" : "https://github.com/rurban/Cpanel-JSON-XS";
       }
    },
-   "version" : "4.12",
+   "version" : "4.14",
    "x_contributors" : [
       "Ashley Willis <[email protected]>",
       "Chip Salzenberg <[email protected]>",
@@ -75,5 +99,5 @@
       "Syohei Yoshida <[email protected]>",
       "tevfik1903 <[email protected]>"
    ],
-   "x_serialization_backend" : "JSON::PP version 4.02"
+   "x_serialization_backend" : "JSON::PP version 2.97001_04"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.12/META.yml 
new/Cpanel-JSON-XS-4.14/META.yml
--- old/Cpanel-JSON-XS-4.12/META.yml    2019-06-11 10:02:48.000000000 +0200
+++ new/Cpanel-JSON-XS-4.14/META.yml    2019-10-15 17:15:06.000000000 +0200
@@ -3,11 +3,24 @@
 author:
   - 'Reini Urban <[email protected]>'
 build_requires:
+  B: '0'
+  Config: '0'
+  Data::Dumper: '0'
+  Devel::Peek: '0'
   ExtUtils::MakeMaker: '0'
+  POSIX: '0'
+  Test: '0'
+  Test::More: '0'
+  Tie::Array: '0'
+  Tie::Hash: '0'
+  charnames: '0'
+  lib: '0'
+  utf8: '0'
 configure_requires:
+  Config: '0'
   ExtUtils::MakeMaker: '0'
 dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 7.36, CPAN::Meta::Converter version 
2.150010'
+generated_by: 'ExtUtils::MakeMaker version 8.3508, CPAN::Meta::Converter 
version 2.150010'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -18,12 +31,19 @@
     - t
     - inc
 requires:
+  Carp: '0'
+  Encode: '1.9801'
+  Exporter: '0'
   Pod::Text: '2.08'
+  XSLoader: '0'
+  overload: '0'
+  strict: '0'
+  warnings: '0'
 resources:
   bugtracker: https://github.com/rurban/Cpanel-JSON-XS/issues
   license: http://dev.perl.org/licenses/
   repository: https://github.com/rurban/Cpanel-JSON-XS
-version: '4.12'
+version: '4.14'
 x_contributors:
   - 'Ashley Willis <[email protected]>'
   - 'Chip Salzenberg <[email protected]>'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.12/Makefile.PL 
new/Cpanel-JSON-XS-4.14/Makefile.PL
--- old/Cpanel-JSON-XS-4.12/Makefile.PL 2019-06-11 09:24:57.000000000 +0200
+++ new/Cpanel-JSON-XS-4.14/Makefile.PL 2019-10-15 16:57:26.000000000 +0200
@@ -50,8 +50,33 @@
   EXE_FILES    => [ "bin/cpanel_json_xs" ],
   VERSION_FROM => "XS.pm",
   NAME         => "Cpanel::JSON::XS",
+  CONFIGURE_REQUIRES => {
+    'Config'              => 0,
+    'ExtUtils::MakeMaker' => 0,
+  },
   PREREQ_PM    => {
+    'overload'      => 0,
+    'strict'        => 0,
+    'warnings'      => 0,
+    'Carp'          => 0,
+    'Encode'        => '1.9801',
+    'Exporter'      => 0,
     'Pod::Text'     => '2.08',
+    'XSLoader'      => 0,
+  },
+  TEST_REQUIRES => {
+    'charnames'     => 0,
+    'lib'           => 0,
+    'utf8'          => 0,
+    'B'             => 0,
+    'Config'        => 0,
+    'Data::Dumper'  => 0,
+    'Devel::Peek'   => 0,
+    'POSIX'         => 0,
+    'Test'          => 0,
+    'Test::More'    => 0,
+    'Tie::Array'    => 0,
+    'Tie::Hash'     => 0,
   },
   DEFINE       => $define,
   LICENSE      => 'perl',
@@ -149,7 +174,7 @@
        pod2text \$(VERSION_FROM) > README
 
 release : dist
-       git tag \$(VERSION)
+       -git tag \$(VERSION)
        cpan-upload \$(DISTVNAME).tar\$(SUFFIX)
        git push
        git push --tags
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.12/README 
new/Cpanel-JSON-XS-4.14/README
--- old/Cpanel-JSON-XS-4.12/README      2019-06-11 10:02:50.000000000 +0200
+++ new/Cpanel-JSON-XS-4.14/README      2019-10-15 17:15:07.000000000 +0200
@@ -1382,12 +1382,12 @@
         directly if you want.
 
            encode_json [Cpanel::JSON::XS::false, Cpanel::JSON::XS::true] # 
yields [false,true]
-           encode_json [!1, !0]      # yields [false,true]
+           encode_json [!1, !0], [JSON_TYPE_BOOL, JSON_TYPE_BOOL] # yields 
[false,true]
 
         eq/ne comparisons with true, false:
 
         false is eq to the empty string or the string 'false' or the special
-        empty string "!!0", i.e. "SV_NO", or the numbers 0 or 0.0.
+        empty string "!!0" or "!1", i.e. "SV_NO", or the numbers 0 or 0.0.
 
         true is eq to the string 'true' or to the special string "!0" (i.e.
         "SV_YES") or to the numbers 1 or 1.0.
@@ -1515,7 +1515,7 @@
               $uri->as_string
            }
 
-    2. "convert_blessed" is enabled and the object has a stringification
+    3. "convert_blessed" is enabled and the object has a stringification
     overload.
         In this case, the overloaded "" method of the object is invoked in
         scalar context. It must return a single scalar that can be directly
@@ -1528,10 +1528,10 @@
             package URI;
             use overload '""' => sub { shift->as_string };
 
-    3. "allow_blessed" is enabled.
+    4. "allow_blessed" is enabled.
         The object will be serialized as a JSON null value.
 
-    4. none of the above
+    5. none of the above
         If none of the settings are enabled or the respective methods are
         missing, "Cpanel::JSON::XS" throws an exception.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.12/SIGNATURE 
new/Cpanel-JSON-XS-4.14/SIGNATURE
--- old/Cpanel-JSON-XS-4.12/SIGNATURE   2019-06-11 10:02:50.000000000 +0200
+++ new/Cpanel-JSON-XS-4.14/SIGNATURE   2019-10-15 17:15:07.000000000 +0200
@@ -12,21 +12,21 @@
 not run its Makefile.PL or Build.PL.
 
 -----BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA512
+Hash: SHA256
 
 SHA256 91299da398f097b15d5de71747cc2352811c2f0e1c0a5022e3572a5bd12cd998 
.appveyor.yml
 SHA256 082201a3cbd62a55f2e58ffbb991c4b2bb806de0009bc9497ffcc07202f60855 
.github/FUNDING.yml
-SHA256 6c974ca75369dd4b4c69eaf0f49266d50485171d0c02691ea8675a240ab58440 
.travis.yml
+SHA256 fb7ff638c0af0c5dde7148f2b00836ca1afd14fdde99f874922b98b08725af36 
.travis.yml
 SHA256 c3f2a1a4f66382f796f71a571946722edba53cf3238152b26fd325f4c2f1a20f 
.whitesource
 SHA256 8de3540a3cd7ecc9a9dcb48975fe852c082fe17d4462f87bb72aa7cc47f083ad COPYING
-SHA256 4ab61f60cd32661ce8ac39ac05ba43592147e577c77df4f4723d17cba7ebf443 Changes
+SHA256 2892ea23cb94d6569caa868534c6574fc7b24b303b930a073bd374a264c12b6f Changes
 SHA256 4643190d59c6aa9f3ae61cfc1a3d8899f72c1759cdc23ce6d23258d964f4245c 
MANIFEST
-SHA256 ac3c2a2a18bd09fc3fe40788fc24672a8fad56d25f5e747d9f8e46b45c1391fd 
META.json
-SHA256 84d1ea68c9ecd0522e84c5db99ce4919d8f7b57f9130b6ee081845dd257d92a8 
META.yml
-SHA256 0161feeade3462743c01c6f1ed7d0d3d2ed0ab2dfe12e77b3b72370df52f636f 
Makefile.PL
-SHA256 ab463d236ae0555d6ccf117219ea743d50922357dd03fc9e1ee1105d49a3003f README
-SHA256 84c51a3379a08dc4548d36842eddfcd76a84fab1f3242ab966c0f87df040a9b7 XS.pm
-SHA256 727e103c3cf2dfc5d59aa68b3dddafb84b3cee7b79464d02922c1bb23f7a50f9 XS.xs
+SHA256 0c6274e9bb94742ac83ef927ee83e0d44f9fa7aaa83f7758d07cda7961726e43 
META.json
+SHA256 40c845877d6825c95218641e8f495af855afbabace97b45f0aac039e39889e61 
META.yml
+SHA256 8b294fe4b791297d24ff18cf2cb1b9857bccce8ea7611fdf4aaa0d2332527881 
Makefile.PL
+SHA256 3f2aea6c904237766823c0b0a631910a5e2589fef7a816a152cb42abfe2ce748 README
+SHA256 e79975a95f00cdfee84d97b13dfdb18732b2f63237773ea2852a8449cdab0b3c XS.pm
+SHA256 2565ff8aa5455abf0810d6f2298982a5c5f74c8777424185353a86731aa9b90e XS.xs
 SHA256 c95e4b970183cbd6d1ec9c88c37a80f12bd2b66ed6be3c008ffd578d2f622c01 
XS/Boolean.pm
 SHA256 ca0447b652d5547206091e8de2799308ffffbe5b5f00a9195641580070573149 
XS/Type.pm
 SHA256 2f34a530b7ce981b0df9aacd2b6944ccf74c4a7f8bb49fde57b342663e7feb26 
bin/cpanel_json_xs
@@ -57,7 +57,7 @@
 SHA256 d8fc2223d440343e68c2c4bb0a62b191c468f9c42b4ef0a361219baf9449b36a 
t/115_tie_ixhash.t
 SHA256 5a7c6c338b74f6f272510723f0605d09c16deba3922e2b29cb4b057d5d6b2bc4 
t/116_incr_parse_fixed.t
 SHA256 08ad2b745ea647529d043e1932c560d70a2655de8749ea473288a747d86284e6 
t/117_numbers.t
-SHA256 1f9489d401f5bc547645010036d28efa8957ccd14deb38ba7175fed4d37ac760 
t/118_type.t
+SHA256 5fe580c7a39a826a3b94af4f9747a5d98a00477ca1defc933f4381772ad5fefb 
t/118_type.t
 SHA256 5f4f0f1d4221f5b5c28c1988f4d127462a42f36ae82fedd7319c8e0fbfbd57eb 
t/119_type_decode.t
 SHA256 8f0f898f0499424740eea5e2537e97faee949b1e3981a1588b1a61645d942d3c 
t/11_pc_expo.t
 SHA256 9807d307292461a749f5e1fe4b3b1469e743ea2413e6e6c19208304ca5926f69 
t/12_blessed.t
@@ -440,12 +440,12 @@
 SHA256 aca6f846869ab2e4881e807739086e1535b1438bd0e23d7a021360742736a6a9 
xt/pod.t
 -----BEGIN PGP SIGNATURE-----
 
-iQEzBAEBCgAdFiEEKJWogdNCcPq/6PdHtPYzOeZdZBQFAlz/YCgACgkQtPYzOeZd
-ZBRdjwgAtr1ZTUNuJQVCyn0ICWUKg3abq3Sq8jOUlHC00OFsTlohSc+fFvDEb2Cu
-aFng8D3j56ERlDfcMHaym8golvk6BT3o4BAa+g6izIcnTHHwO1WUZUDPgAkN0r59
-4OrzPCROScnZwkho0ak0h12pKYC624EHWAPRBwr6ktiQwlYuh8YMPXYm0f/IOMmm
-xCtJXQJ/ActgZaXSY8rTj9Z44s/JDgv7z6ZXJHaJhWxEidFFKGmXTYeQQ6nBngBY
-OvPhy9cDW/8gvvV1LmDwX25yNV936NCAdrEZ4Hx4QTfTO74x5dwuUR6+J+C3ctNF
-c5lZWvpwfWgWUA1gnVq89nNx7D0rHQ==
-=iDAX
+iQEzBAEBCAAdFiEEKJWogdNCcPq/6PdHtPYzOeZdZBQFAl2l4nsACgkQtPYzOeZd
+ZBQS9AgAm6OzEiewIEbUSWguhcqwDviSVjjX+bOACKcxbym/bMwFYgLt5m7BpdQg
+CWXsnp4WaswT0N72z/g4b7qFhAKhHzRcUQQSaE9iivST0eWhVvlLbhI7HiuCGWyt
+Ld5XLs7hCLQGT5KFs+cmmdETHUt1ms9xiQ89IKJmev//apnoyl0hvINpMVZkRf32
+jAiEGcr5gNu916uydxegEEd6ugX67ThnncmKUNY/kqdfOJasb4quMYjipy2twFSi
+ZpU/avmAkEpdty/8jOFjYqKkA5Ul88T8woBck5GSL/s3xg6fw8WVTgbLQpkBIwZD
+g7z83vLEOKV4cujLG0WuY9G8yNpOdw==
+=sT24
 -----END PGP SIGNATURE-----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.12/XS.pm 
new/Cpanel-JSON-XS-4.14/XS.pm
--- old/Cpanel-JSON-XS-4.12/XS.pm       2019-06-11 09:24:57.000000000 +0200
+++ new/Cpanel-JSON-XS-4.14/XS.pm       2019-10-15 16:55:27.000000000 +0200
@@ -1,5 +1,5 @@
 package Cpanel::JSON::XS;
-our $VERSION = '4.12';
+our $VERSION = '4.14';
 our $XS_VERSION = $VERSION;
 # $VERSION = eval $VERSION;
 
@@ -1552,12 +1552,12 @@
 directly if you want.
 
    encode_json [Cpanel::JSON::XS::false, Cpanel::JSON::XS::true] # yields 
[false,true]
-   encode_json [!1, !0]      # yields [false,true]
+   encode_json [!1, !0], [JSON_TYPE_BOOL, JSON_TYPE_BOOL] # yields [false,true]
 
 eq/ne comparisons with true, false:
 
 false is eq to the empty string or the string 'false' or the special
-empty string C<!!0>, i.e. C<SV_NO>, or the numbers 0 or 0.0.
+empty string C<!!0> or C<!1>, i.e. C<SV_NO>, or the numbers 0 or 0.0.
 
 true is eq to the string 'true' or to the special string C<!0>
 (i.e. C<SV_YES>) or to the numbers 1 or 1.0.
@@ -1694,7 +1694,7 @@
       $uri->as_string
    }
 
-=item 2. C<convert_blessed> is enabled and the object has a stringification 
overload.
+=item 3. C<convert_blessed> is enabled and the object has a stringification 
overload.
 
 In this case, the overloaded C<""> method of the object is invoked in scalar
 context. It must return a single scalar that can be directly encoded into
@@ -1707,11 +1707,11 @@
     package URI;
     use overload '""' => sub { shift->as_string };
 
-=item 3. C<allow_blessed> is enabled.
+=item 4. C<allow_blessed> is enabled.
 
 The object will be serialized as a JSON null value.
 
-=item 4. none of the above
+=item 5. none of the above
 
 If none of the settings are enabled or the respective methods are missing,
 C<Cpanel::JSON::XS> throws an exception.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.12/XS.xs 
new/Cpanel-JSON-XS-4.14/XS.xs
--- old/Cpanel-JSON-XS-4.12/XS.xs       2019-06-11 08:59:13.000000000 +0200
+++ new/Cpanel-JSON-XS-4.14/XS.xs       2019-10-14 14:25:59.000000000 +0200
@@ -85,6 +85,57 @@
 #define STR_NAN "nan"
 #endif
 
+/* NV_INF compatibility for Perl 5.6 */
+#if !defined(NV_INF) && defined(USE_LONG_DOUBLE) && defined(LDBL_INFINITY)
+#  define NV_INF LDBL_INFINITY
+#endif
+#if !defined(NV_INF) && defined(DBL_INFINITY)
+#  define NV_INF (NV)DBL_INFINITY
+#endif
+#if !defined(NV_INF) && defined(INFINITY)
+#  define NV_INF (NV)INFINITY
+#endif
+#if !defined(NV_INF) && defined(INF)
+#  define NV_INF (NV)INF
+#endif
+#if !defined(NV_INF) && defined(USE_LONG_DOUBLE) && defined(HUGE_VALL)
+#  define NV_INF (NV)HUGE_VALL
+#endif
+#if !defined(NV_INF) && defined(HUGE_VAL)
+#  define NV_INF (NV)HUGE_VAL
+#endif
+
+/* NV_NAN compatibility for Perl 5.6 */
+#if !defined(NV_NAN) && defined(USE_LONG_DOUBLE)
+#   if !defined(NV_NAN) && defined(LDBL_NAN)
+#       define NV_NAN LDBL_NAN
+#   endif
+#   if !defined(NV_NAN) && defined(LDBL_QNAN)
+#       define NV_NAN LDBL_QNAN
+#   endif
+#   if !defined(NV_NAN) && defined(LDBL_SNAN)
+#       define NV_NAN LDBL_SNAN
+#   endif
+#endif
+#if !defined(NV_NAN) && defined(DBL_NAN)
+#  define NV_NAN (NV)DBL_NAN
+#endif
+#if !defined(NV_NAN) && defined(DBL_QNAN)
+#  define NV_NAN (NV)DBL_QNAN
+#endif
+#if !defined(NV_NAN) && defined(DBL_SNAN)
+#  define NV_NAN (NV)DBL_SNAN
+#endif
+#if !defined(NV_NAN) && defined(QNAN)
+#  define NV_NAN (NV)QNAN
+#endif
+#if !defined(NV_NAN) && defined(SNAN)
+#  define NV_NAN (NV)SNAN
+#endif
+#if !defined(NV_NAN) && defined(NAN)
+#  define NV_NAN (NV)NAN
+#endif
+
 /* modfl() segfaults for -Duselongdouble && 64-bit mingw64 && mingw
    runtime version 4.0 [perl #125924] */
 #if defined(USE_LONG_DOUBLE) && defined(__MINGW64__) \
@@ -676,6 +727,25 @@
   return neg ? -accum : accum;
 }
 
+INLINE int
+is_bignum_obj (pTHX_ SV *sv)
+{
+  HV *stash = SvSTASH (sv);
+  return (stash == gv_stashpvs ("Math::BigInt", 0) || stash == gv_stashpvs 
("Math::BigFloat", 0)) ? 1 : 0;
+}
+
+INLINE int
+is_bool_obj (pTHX_ SV *sv)
+{
+  dMY_CXT;
+
+  HV *bstash   = MY_CXT.json_boolean_stash; /* JSON-XS-3.x interop 
(Types::Serialiser/JSON::PP::Boolean) */
+  HV *oldstash = MY_CXT.jsonold_boolean_stash; /* JSON-XS-2.x interop 
(JSON::XS::Boolean) */
+  HV *mstash   = MY_CXT.mojo_boolean_stash; /* Mojo::JSON::_Bool interop */
+  HV *stash    = SvSTASH (sv);
+
+  return (stash == bstash || stash == mstash || stash == oldstash) ? 1 : 0;
+}
 
 /* target of scalar reference is bool?  -1 == nope, 0 == false, 1 == true */
 static int
@@ -712,16 +782,8 @@
   if (!SvOBJECT (scalar) && ref_bool_type (aTHX_ scalar) >= 0)
     return 1;
 
-  if (SvOBJECT (scalar)) {
-    dMY_CXT;
-    HV *bstash   = MY_CXT.json_boolean_stash;
-    HV *oldstash = MY_CXT.jsonold_boolean_stash;
-    HV *mstash   = MY_CXT.mojo_boolean_stash;
-    HV *stash    = SvSTASH (scalar);
-
-    if (stash == bstash || stash == mstash || stash == oldstash)
-      return 1;
-  }
+  if (SvOBJECT (scalar) && is_bool_obj (aTHX_ scalar))
+    return 1;
   
   return 0;
 }
@@ -1442,10 +1504,7 @@
         && (memEQc(str, "NaN") || memEQc(str, "nan") ||
             memEQc(str, "inf") || memEQc(str, "-inf"))))
   {
-    HV *stash = SvSTASH(SvRV(sv));
-    if (stash
-        && ((stash == gv_stashpvn ("Math::BigInt", sizeof("Math::BigInt")-1, 
0)) ||
-            (stash == gv_stashpvn ("Math::BigFloat", 
sizeof("Math::BigFloat")-1, 0))))
+    if (is_bignum_obj (aTHX_ SvRV (sv)))
     {
       if (enc->json.infnan_mode == 0) {
         encode_const_str (aTHX_ enc, "null", 4, 0);
@@ -1478,14 +1537,7 @@
 INLINE int
 encode_bool_obj (pTHX_ enc_t *enc, SV *sv, int force_conversion, int as_string)
 {
-  dMY_CXT;
-
-  HV *bstash   = MY_CXT.json_boolean_stash; /* JSON-XS-3.x interop 
(Types::Serialiser/JSON::PP::Boolean) */
-  HV *oldstash = MY_CXT.jsonold_boolean_stash; /* JSON-XS-2.x interop 
(JSON::XS::Boolean) */
-  HV *mstash   = MY_CXT.mojo_boolean_stash; /* Mojo::JSON::_Bool interop */
-  HV *stash    = SvSTASH (sv);
-
-  if (stash == bstash || stash == mstash || stash == oldstash)
+  if (is_bool_obj (aTHX_ sv))
     {
       if (as_string)
         encode_ch (aTHX_ enc, '"');
@@ -1615,10 +1667,7 @@
 
           FREETMPS; LEAVE;
         }
-      else if ((enc->json.flags & F_ALLOW_BIGNUM)
-               && stash
-               && ((stash == gv_stashpvn ("Math::BigInt", 
sizeof("Math::BigInt")-1, 0))
-                || (stash == gv_stashpvn ("Math::BigFloat", 
sizeof("Math::BigFloat")-1, 0))))
+      else if ((enc->json.flags & F_ALLOW_BIGNUM) && is_bignum_obj (aTHX_ sv))
         encode_stringify(aTHX_ enc, rv, 1);
       else if (enc->json.flags & F_CONV_BLESSED)
         encode_stringify(aTHX_ enc, sv, 0);
@@ -1736,6 +1785,9 @@
 
   if (UNLIKELY (SvOK (typesv)))
     {
+      if (SvROK (sv) && SvOBJECT (SvRV (sv)) && !(enc->json.flags & 
(F_ALLOW_TAGS|F_CONV_BLESSED|F_ALLOW_BLESSED)) && !is_bool_obj (aTHX_ SvRV 
(sv)) && !is_bignum_obj (aTHX_ SvRV (sv)))
+        croak ("encountered object '%s', but neither allow_blessed, 
convert_blessed nor allow_tags settings are enabled (or TO_JSON/FREEZE method 
missing)", SvPV_nolen (sv));
+
       if (!SvIOKp (typesv))
         {
           if (SvROK (typesv) &&
@@ -1792,6 +1844,7 @@
     encode_bool (aTHX_ enc, sv);
   else if (type == JSON_TYPE_FLOAT)
     {
+      int is_bigobj = 0;
       char *savecur, *saveend;
       char inf_or_nan = 0;
 #ifdef NEED_NUMERIC_LOCALE_C
@@ -1802,151 +1855,302 @@
       bool loc_changed = FALSE;
       char *locale = NULL;
 #endif
-      NV nv = SvNOKp (sv) ? SvNVX (sv) : SvNV_nomg (sv);
-      /* trust that perl will do the right thing w.r.t. JSON syntax. */
-      need (aTHX_ enc, NV_DIG + 32);
-      savecur = enc->cur;
-      saveend = enc->end;
+      NV nv = 0;
+      int had_nokp = SvNOKp(sv);
 
-#if defined(HAVE_ISINF) && defined(HAVE_ISNAN)
-      /* With no stringify_infnan we can skip the conversion, returning null. 
*/
-      if (enc->json.infnan_mode == 0) {
-# if defined(USE_QUADMATH) && defined(HAVE_ISINFL) && defined(HAVE_ISNANL)
-        if (UNLIKELY(isinfl(nv) || isnanl(nv)))
-# else
-        if (UNLIKELY(isinf(nv) || isnan(nv)))
-# endif
+      if (UNLIKELY (SvROK (sv) && SvOBJECT (SvRV (sv))) && (enc->json.flags & 
F_ALLOW_BIGNUM) && is_bignum_obj (aTHX_ SvRV (sv)))
+        is_bigobj = 1;
+
+      if (UNLIKELY (is_bigobj))
+        {
+          STRLEN len;
+          char *str = SvPV_nomg (sv, len);
+          if (UNLIKELY (str[0] == '+'))
+            {
+              str++;
+              len--;
+            }
+          if (UNLIKELY (memEQc (str, "NaN") || memEQc (str, "nan")))
+            {
+              nv = NV_NAN;
+              is_bigobj = 0;
+            }
+          else if (UNLIKELY (memEQc (str, "inf")))
+            {
+              nv = NV_INF;
+              is_bigobj = 0;
+            }
+          else if (UNLIKELY (memEQc (str, "-inf")))
+            {
+              nv = -NV_INF;
+              is_bigobj = 0;
+            }
+          else
+            {
+              need (aTHX_ enc, len+1+2); /* +2 for '.0' */
+              savecur = enc->cur;
+              saveend = enc->end;
+              memcpy (enc->cur, str, len);
+              *(enc->cur+len) = '\0';
+            }
+        }
+      else if (SvNOKp (sv))
         {
-          goto is_inf_or_nan;
+          nv = SvNVX (sv);
         }
-      }
+      else
+        {
+          if (enc->json.flags & F_ALLOW_BIGNUM)
+            {
+              STRLEN len;
+              char *str;
+              SV *pv;
+              SV *errsv;
+              int numtype;
+
+              str = SvPV_nomg (sv, len);
+
+              numtype = grok_number (str, len, NULL);
+              if (UNLIKELY (numtype & IS_NUMBER_INFINITY))
+                nv = (numtype & IS_NUMBER_NEG) ? -NV_INF : NV_INF;
+              else if (UNLIKELY (numtype & IS_NUMBER_NAN))
+                nv = NV_NAN;
+              else if (UNLIKELY (!numtype))
+                nv = SvNV_nomg (sv);
+              else
+                {
+                  pv = newSVpvs ("require Math::BigFloat && 
Math::BigFloat->new(\"");
+                  sv_catpvn (pv, str, len);
+                  sv_catpvs (pv, "\");");
+
+                  eval_sv (pv, G_SCALAR);
+                  SvREFCNT_dec (pv);
+
+                  /* rethrow current error */
+                  errsv = ERRSV;
+                  if (SvROK (errsv))
+                    croak (NULL);
+                  else if (SvTRUE (errsv))
+                    croak ("%" SVf, SVfARG (errsv));
+
+                  {
+                    dSP;
+                    pv = POPs;
+                    PUTBACK;
+                  }
+
+                  str = SvPV (pv, len);
+                  if (UNLIKELY (str[0] == '+'))
+                    {
+                      str++;
+                      len--;
+                    }
+                  need (aTHX_ enc, len+1);
+                  savecur = enc->cur;
+                  saveend = enc->end;
+                  memcpy (enc->cur, str, len);
+                  *(enc->cur+len) = '\0';
+                  is_bigobj = 1;
+                }
+            }
+          else
+            {
+
+#if PERL_VERSION < 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 8)
+              if (SvPOKp (sv))
+                {
+                  int numtype = grok_number (SvPVX (sv), SvCUR (sv), NULL);
+                  if (UNLIKELY (numtype & IS_NUMBER_INFINITY))
+                    nv = (numtype & IS_NUMBER_NEG) ? -NV_INF : NV_INF;
+                  else if (UNLIKELY (numtype & IS_NUMBER_NAN))
+                    nv = NV_NAN;
+                  else
+                    nv = SvNV_nomg (sv);
+                }
+              else
+                {
+                  nv = SvNV_nomg (sv);
+                }
+#else
+              nv = SvNV_nomg (sv);
 #endif
-      /* locale insensitive sprintf radix #96 */
+            }
+        }
+
+      if (LIKELY (!is_bigobj))
+        {
+          /* trust that perl will do the right thing w.r.t. JSON syntax. */
+          need (aTHX_ enc, NV_DIG + 32);
+          savecur = enc->cur;
+          saveend = enc->end;
+
+          if (force_conversion)
+            {
+              had_nokp = 0;
+#if defined(USE_QUADMATH) && defined(HAVE_ISINFL)
+              if (UNLIKELY(isinfl(nv)))
+#else
+              if (UNLIKELY(isinf(nv)))
+#endif
+                nv = (nv > 0) ? NV_MAX : -NV_MAX;
+#if defined(USE_QUADMATH) && defined(HAVE_ISNANL)
+              if (UNLIKELY(isnanl(nv)))
+#else
+              if (UNLIKELY(isnan(nv)))
+#endif
+                nv = 0;
+            }
+          /* With no stringify_infnan we can skip the conversion, returning 
null. */
+          else if (enc->json.infnan_mode == 0)
+            {
+#if defined(USE_QUADMATH) && defined(HAVE_ISINFL)
+              if (UNLIKELY(isinfl(nv)))
+#else
+              if (UNLIKELY(isinf(nv)))
+#endif
+                {
+                  inf_or_nan = (nv > 0) ? 1 : 2;
+                  goto is_inf_or_nan;
+                }
+#if defined(USE_QUADMATH) && defined(HAVE_ISNANL)
+              if (UNLIKELY(isnanl(nv)))
+#else
+              if (UNLIKELY(isnan(nv)))
+#endif
+                {
+                  inf_or_nan = 3;
+                  goto is_inf_or_nan;
+                }
+            }
+          /* locale insensitive sprintf radix #96 */
 #ifdef NEED_NUMERIC_LOCALE_C
-      locale = setlocale(LC_NUMERIC, NULL);
-      if (!locale || strNE(locale, "C")) {
-        loc_changed = TRUE;
+          locale = setlocale(LC_NUMERIC, NULL);
+          if (!locale || strNE(locale, "C"))
+            {
+              loc_changed = TRUE;
 # ifdef HAS_USELOCALE
-        /* thread-safe variant for children not changing the global state */
-        oldloc = uselocale((locale_t)0);
-        if (oldloc == LC_GLOBAL_LOCALE)
-          newloc = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0);
-        else
-          newloc = newlocale(LC_NUMERIC_MASK, "C", oldloc);
-        uselocale(newloc);
+              /* thread-safe variant for children not changing the global 
state */
+              oldloc = uselocale((locale_t)0);
+              if (oldloc == LC_GLOBAL_LOCALE)
+                newloc = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0);
+              else
+                newloc = newlocale(LC_NUMERIC_MASK, "C", oldloc);
+              uselocale(newloc);
 # else
-        setlocale(LC_NUMERIC, "C");
+              setlocale(LC_NUMERIC, "C");
 # endif
-      }
+            }
 #endif
 
 #ifdef USE_QUADMATH
-      quadmath_snprintf(enc->cur, enc->end - enc->cur, "%.*Qg", (int)NV_DIG, 
nv);
+          quadmath_snprintf(enc->cur, enc->end - enc->cur, "%.*Qg", 
(int)NV_DIG, nv);
 #else
-      PERL_UNUSED_RESULT(Gconvert (nv, NV_DIG, 0, enc->cur));
+          PERL_UNUSED_RESULT(Gconvert (nv, NV_DIG, 0, enc->cur));
 #endif
 
 #ifdef NEED_NUMERIC_LOCALE_C
-      if (loc_changed) {
+          if (loc_changed)
+            {
 # ifdef HAS_USELOCALE
-        (void)uselocale(oldloc);
-        if (newloc)
-          freelocale(newloc);
+              (void)uselocale(oldloc);
+              if (newloc)
+                freelocale(newloc);
 # else
-        (void)setlocale(LC_NUMERIC, locale);
+              (void)setlocale(LC_NUMERIC, locale);
 # endif
-      }
+            }
 #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)))
+          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)))
+          if (UNLIKELY(strEQc(enc->cur, STR_INF)
+                       || strEQc(enc->cur, STR_INF2)))
 #else
-      if (UNLIKELY(strEQc(enc->cur, STR_INF)))
+          if (UNLIKELY(strEQc(enc->cur, STR_INF)))
 #endif
-        inf_or_nan = 1;
+            inf_or_nan = 1;
 #if defined(__hpux)
-      else if (UNLIKELY(strEQc(enc->cur, STR_NEG_INF)))
-        inf_or_nan = 2;
-      else if (UNLIKELY(strEQc(enc->cur, STR_NEG_NAN)))
-        inf_or_nan = 3;
+          else if (UNLIKELY(strEQc(enc->cur, STR_NEG_INF)))
+            inf_or_nan = 2;
+          else if (UNLIKELY(strEQc(enc->cur, STR_NEG_NAN)))
+            inf_or_nan = 3;
 #endif
-      else if
+          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)))
+            (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)))
+            (UNLIKELY(strEQc(enc->cur, STR_NAN)
+                      || strEQc(enc->cur, STR_QNAN)))
 # endif
 #else
-        (UNLIKELY(strEQc(enc->cur, STR_NAN)))
+            (UNLIKELY(strEQc(enc->cur, STR_NAN)))
 #endif
-        inf_or_nan = 3;
-      else if (*enc->cur == '-') {
+            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)))
+            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)))
+            if (UNLIKELY(strEQc(enc->cur+1, STR_INF)
+                       || strEQc(enc->cur+1, STR_INF2)))
 #else
-        if (UNLIKELY(strEQc(enc->cur+1, STR_INF)))
+            if (UNLIKELY(strEQc(enc->cur+1, STR_INF)))
 #endif
-          inf_or_nan = 2;
-        else if
+              inf_or_nan = 2;
+            else if
 #ifdef HAVE_QNAN
 # ifdef STR_QNAN2
-          (UNLIKELY(strEQc(enc->cur+1, STR_NAN)
+              (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)
+              (UNLIKELY(strEQc(enc->cur+1, STR_NAN)
                     || strEQc(enc->cur+1, STR_QNAN)))
 # endif
 #else
-          (UNLIKELY(strEQc(enc->cur+1, STR_NAN)))
+              (UNLIKELY(strEQc(enc->cur+1, STR_NAN)))
 #endif
-            inf_or_nan = 3;
-      }
-      if (UNLIKELY(inf_or_nan)) {
-#if defined(HAVE_ISINF) && defined(HAVE_ISNAN)
-      is_inf_or_nan:
-#endif
-        if (enc->json.infnan_mode == 0) {
-          strncpy(enc->cur, "null\0", 5);
-        }
-        else if (enc->json.infnan_mode == 1) {
-          const int l = strlen(enc->cur);
-          memmove(enc->cur+1, enc->cur, l);
-          *enc->cur = '"';
-          *(enc->cur + l+1) = '"';
-          *(enc->cur + l+2) = 0;
-        }
-        else if (enc->json.infnan_mode == 3) {
-          if (inf_or_nan == 1)
-            strncpy(enc->cur, "\"inf\"\0", 6);
-          else if (inf_or_nan == 2)
-            strncpy(enc->cur, "\"-inf\"\0", 7);
-          else if (inf_or_nan == 3)
-            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);
+                inf_or_nan = 3;
+          }
+          if (UNLIKELY(inf_or_nan)) {
+          is_inf_or_nan:
+            if (enc->json.infnan_mode == 0) {
+              strncpy(enc->cur, "null\0", 5);
+            }
+            else if (enc->json.infnan_mode == 1) {
+              const int l = strlen(enc->cur);
+              memmove(enc->cur+1, enc->cur, l);
+              *enc->cur = '"';
+              *(enc->cur + l+1) = '"';
+              *(enc->cur + l+2) = 0;
+            }
+            else if (enc->json.infnan_mode == 3) {
+              if (inf_or_nan == 1)
+                strncpy(enc->cur, "\"inf\"\0", 6);
+              else if (inf_or_nan == 2)
+                strncpy(enc->cur, "\"-inf\"\0", 7);
+              else if (inf_or_nan == 3)
+                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);
+            }
+          }
+
         }
-      }
+
       if (!force_conversion && SvPOKp (sv) && !strEQ(enc->cur, SvPVX (sv))) {
         char *str = SvPVX (sv);
         STRLEN len = SvCUR (sv);
@@ -1959,8 +2163,8 @@
       }
       else {
         NV intpart;
-        if (!( inf_or_nan || (SvNOKp(sv) && Perl_modf(SvNVX(sv), &intpart)) || 
(!force_conversion && SvIOK(sv))
-            || strchr(enc->cur,'e') || strchr(enc->cur,'E')
+        if (!( inf_or_nan || (had_nokp && Perl_modf(SvNVX(sv), &intpart)) || 
(!force_conversion && SvIOK(sv))
+            || strchr(enc->cur,'e') || strchr(enc->cur,'E') || 
strchr(savecur,'.')
 #if PERL_VERSION < 10
                /* !!1 with 5.8 */
                || (SvPOKp(sv) && strEQc(SvPVX(sv), "1")
@@ -1983,7 +2187,98 @@
       UV uv = 0;
       IV iv = 0;
       int is_neg = 0;
-      if (SvIOKp (sv))
+
+      if (UNLIKELY (SvROK (sv) && SvOBJECT (SvRV (sv))) && (enc->json.flags & 
F_ALLOW_BIGNUM))
+        {
+          HV *stash = SvSTASH (SvRV (sv));
+          int is_bigint = (stash && stash == gv_stashpvs ("Math::BigInt", 0));
+          int is_bigfloat = (stash && stash == gv_stashpvs ("Math::BigFloat", 
0));
+
+          if (is_bigint || is_bigfloat)
+            {
+              STRLEN len;
+              char *str;
+
+              if (is_bigfloat)
+                {
+                  dSP;
+                  int is_negative;
+
+                  ENTER;
+                  SAVETMPS;
+
+                  PUSHMARK (SP);
+                  XPUSHs (sv);
+                  PUTBACK;
+
+                  call_method ("is_negative", G_SCALAR);
+
+                  SPAGAIN;
+                  is_negative = SvTRUEx (POPs);
+                  PUTBACK;
+
+                  PUSHMARK (SP);
+                  XPUSHs (sv);
+                  PUTBACK;
+
+                  /* This bceil/bfloor logic can be replaced by just one 
"bint" method call
+                   * but it is not supported by older Math::BigFloat versions.
+                   * Older Math::BigFloat versions have also "as_number" 
method which should
+                   * do same thing as "bint" method but it is broken and loose 
precision.
+                   * This bceil/bfloor logic needs Math::BigFloat 1.16 which 
is in Perl 5.8.0. */
+                  call_method (is_negative ? "bceil" : "bfloor", G_SCALAR);
+
+                  SPAGAIN;
+                  sv = POPs;
+                  PUTBACK;
+                }
+
+              str = SvPV_nomg (sv, len);
+              if (UNLIKELY (str[0] == '+'))
+                {
+                  str++;
+                  len--;
+                }
+
+              if (UNLIKELY (strEQc (str, "NaN") || strEQc (str, "nan")))
+                {
+                  encode_const_str (aTHX_ enc, "0", 1, 0);
+                }
+              else if (UNLIKELY (strEQc (str, "inf")))
+                {
+                  need (aTHX_ enc, IVUV_MAXCHARS);
+                  savecur = enc->cur;
+                  saveend = enc->end;
+                  enc->cur += snprintf (enc->cur, IVUV_MAXCHARS, "%" UVuf, 
UV_MAX);
+                }
+              else if (UNLIKELY (strEQc (str, "-inf")))
+                {
+                  need (aTHX_ enc, IVUV_MAXCHARS);
+                  savecur = enc->cur;
+                  saveend = enc->end;
+                  enc->cur += snprintf (enc->cur, IVUV_MAXCHARS, "%" IVdf, 
IV_MIN);
+                }
+              else
+                {
+                  need (aTHX_ enc, len+1);
+                  savecur = enc->cur;
+                  saveend = enc->end;
+                  memcpy (enc->cur, str, len);
+                  enc->cur += len;
+                  *enc->cur = '\0';
+                }
+
+              if (is_bigfloat)
+                {
+                  FREETMPS;
+                  LEAVE;
+                }
+
+              return;
+            }
+        }
+
+      if (SvIOK (sv))
         {
           is_neg = !SvIsUV (sv);
           iv = SvIVX (sv);
@@ -2000,7 +2295,10 @@
                   if (LIKELY(uv <= (UV)(IV_MAX) + 1))
                     iv = -(IV)uv;
                   else
-                    iv = IV_MIN; /* underflow */
+                    {
+                      iv = IV_MIN; /* underflow, but F_ALLOW_BIGNUM can handle 
this */
+                      numtype |= IS_NUMBER_GREATER_THAN_UV_MAX;
+                    }
                   uv = (UV)iv;
                 }
               else
@@ -2020,7 +2318,63 @@
                   iv = (IV)uv;
                 }
             }
-          else if (LIKELY (!(numtype & IS_NUMBER_NAN)))
+
+          if ((numtype & (IS_NUMBER_GREATER_THAN_UV_MAX|IS_NUMBER_NOT_INT)) && 
(enc->json.flags & F_ALLOW_BIGNUM))
+            {
+              STRLEN len;
+              char *str;
+              SV *pv;
+              SV *errsv;
+
+              if (numtype & IS_NUMBER_NOT_INT)
+                pv = newSVpvs ("my $obj; require Math::BigFloat && ($obj = 
Math::BigFloat->new(\"");
+              else
+                pv = newSVpvs ("require Math::BigInt && return 
Math::BigInt->new(\"");
+
+              sv_catpvn (pv, SvPVX (sv), SvCUR (sv));
+
+              if (numtype & IS_NUMBER_NOT_INT)
+                /* This bceil/bfloor logic can be replaced by just one "bint" 
method call
+                 * but it is not supported by older Math::BigFloat versions.
+                 * Older Math::BigFloat versions have also "as_number" method 
which should
+                 * do same thing as "bint" method but it is broken and loose 
precision.
+                 * This bceil/bfloor logic needs Math::BigFloat 1.16 which is 
in Perl 5.8.0. */
+                sv_catpvs (pv, "\")) && ($obj->is_negative ? $obj->bceil : 
$obj->bfloor);");
+              else
+                sv_catpvs (pv, "\");");
+
+              eval_sv (pv, G_SCALAR);
+              SvREFCNT_dec (pv);
+
+              /* rethrow current error */
+              errsv = ERRSV;
+              if (SvROK (errsv))
+                croak (NULL);
+              else if (SvTRUE (errsv))
+                croak ("%" SVf, SVfARG (errsv));
+
+              {
+                dSP;
+                pv = POPs;
+                PUTBACK;
+              }
+
+              str = SvPV (pv, len);
+              if (UNLIKELY (str[0] == '+'))
+                {
+                  str++;
+                  len--;
+                }
+              need (aTHX_ enc, len+1);
+              savecur = enc->cur;
+              saveend = enc->end;
+              memcpy (enc->cur, str, len);
+              enc->cur += len;
+              *enc->cur = '\0';
+
+              return;
+            }
+          else if (!(numtype & 
(IS_NUMBER_IN_UV|IS_NUMBER_INFINITY|IS_NUMBER_NAN)))
             {
               sv_to_ivuv (aTHX_ sv, &is_neg, &iv, &uv);
             }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.12/t/118_type.t 
new/Cpanel-JSON-XS-4.14/t/118_type.t
--- old/Cpanel-JSON-XS-4.12/t/118_type.t        2019-06-10 15:26:34.000000000 
+0200
+++ new/Cpanel-JSON-XS-4.14/t/118_type.t        2019-10-15 16:55:27.000000000 
+0200
@@ -14,9 +14,10 @@
     }
 }
 
-use Test::More tests => 307;
+use Test::More tests => 381;
 
 my $cjson = Cpanel::JSON::XS->new->canonical->allow_nonref->require_types;
+my $bigcjson = 
Cpanel::JSON::XS->new->canonical->allow_nonref->require_types->allow_bignum;
 
 foreach my $false (Cpanel::JSON::XS::false, undef, 0, 0.0, 0E0, !!0, !1, "0", 
"", \0) {
     is($cjson->encode($false, JSON_TYPE_BOOL), 'false');
@@ -169,6 +170,163 @@
  }
 }
 
+SKIP: {
+  skip 'requires Math::BigInt', 5 unless eval { require Math::BigInt };
+  # integer string values outside of range [IV_MIN, UV_MAX] with enabled bignum
+  is($bigcjson->encode('18446744073709551616', JSON_TYPE_INT), 
'18446744073709551616');  #  2^64
+  is($bigcjson->encode('18446744073709551617', JSON_TYPE_INT), 
'18446744073709551617');  #  2^64+1
+  is($bigcjson->encode('18446744073709551618', JSON_TYPE_INT), 
'18446744073709551618');  #  2^64+2
+  is($bigcjson->encode('-9223372036854775809', JSON_TYPE_INT), 
'-9223372036854775809');  # -2^63-1
+  is($bigcjson->encode('-9223372036854775810', JSON_TYPE_INT), 
'-9223372036854775810');  # -2^63-2
+}
+
+SKIP: {
+  skip 'requires Math::BigFloat 1.16', 6 unless eval { require Math::BigFloat; 
Math::BigFloat->VERSION(1.16) };
+  # float string values outside of range [IV_MIN, UV_MAX] with enabled bignum
+  is($bigcjson->encode('18446744073709551616.5', JSON_TYPE_INT), 
'18446744073709551616');  #  2^64
+  is($bigcjson->encode('18446744073709551617.5', JSON_TYPE_INT), 
'18446744073709551617');  #  2^64+1
+  is($bigcjson->encode('18446744073709551618.5', JSON_TYPE_INT), 
'18446744073709551618');  #  2^64+2
+  is($bigcjson->encode('-9223372036854775809.5', JSON_TYPE_INT), 
'-9223372036854775809');  # -2^63-1
+  is($bigcjson->encode('-9223372036854775810.5', JSON_TYPE_INT), 
'-9223372036854775810');  # -2^63-2
+  is($bigcjson->encode(  '7.37869762948382e+19', JSON_TYPE_INT), 
'73786976294838200000');
+}
+
+SKIP: {
+  skip 'requires Math::BigInt', 8 unless eval { require Math::BigInt };
+
+  # Math::BigInt values outside of range [IV_MIN, UV_MAX] with enabled bignum
+  is($bigcjson->encode(Math::BigInt->new('18446744073709551616'), 
JSON_TYPE_INT), '18446744073709551616');  #  2^64
+  is($bigcjson->encode(Math::BigInt->new('18446744073709551617'), 
JSON_TYPE_INT), '18446744073709551617');  #  2^64+1
+  is($bigcjson->encode(Math::BigInt->new('18446744073709551618'), 
JSON_TYPE_INT), '18446744073709551618');  #  2^64+2
+  is($bigcjson->encode(Math::BigInt->new('-9223372036854775809'), 
JSON_TYPE_INT), '-9223372036854775809');  # -2^63-1
+  is($bigcjson->encode(Math::BigInt->new('-9223372036854775810'), 
JSON_TYPE_INT), '-9223372036854775810');  # -2^63-2
+
+  is($bigcjson->encode(Math::BigInt->new('NaN'), JSON_TYPE_INT), '0');
+
+  if ($Config{ivsize} == 4) {
+    is($bigcjson->encode(Math::BigInt->new('+inf'), JSON_TYPE_INT), 
'4294967295');
+    is($bigcjson->encode(Math::BigInt->new('-inf'), JSON_TYPE_INT), 
'-2147483648');
+  } elsif ($Config{ivsize} == 8 && $] > 5.008) {
+    is($bigcjson->encode(Math::BigInt->new('+inf'), JSON_TYPE_INT), 
'18446744073709551615');
+    is($bigcjson->encode(Math::BigInt->new('-inf'), JSON_TYPE_INT), 
'-9223372036854775808');
+  } else {
+    skip "unknown ivsize $Config{ivsize} or too old", 2;
+  }
+}
+
+SKIP: {
+  skip 'requires Math::BigFloat 1.16', 8 unless eval { require Math::BigFloat; 
Math::BigFloat->VERSION(1.16) };
+  # Math::BigFloat values outside of range [IV_MIN, UV_MAX] with enabled bignum
+  is($bigcjson->encode(Math::BigFloat->new('18446744073709551616.5'), 
JSON_TYPE_INT), '18446744073709551616');  #  2^64
+  is($bigcjson->encode(Math::BigFloat->new('18446744073709551617.5'), 
JSON_TYPE_INT), '18446744073709551617');  #  2^64+1
+  is($bigcjson->encode(Math::BigFloat->new('18446744073709551618.5'), 
JSON_TYPE_INT), '18446744073709551618');  #  2^64+2
+  is($bigcjson->encode(Math::BigFloat->new('-9223372036854775809.5'), 
JSON_TYPE_INT), '-9223372036854775809');  # -2^63-1
+  is($bigcjson->encode(Math::BigFloat->new('-9223372036854775810.5'), 
JSON_TYPE_INT), '-9223372036854775810');  # -2^63-2
+
+  is($bigcjson->encode(Math::BigFloat->new('NaN'), JSON_TYPE_INT), '0');
+  if ($Config{ivsize} == 4) {
+    is($bigcjson->encode(Math::BigFloat->new('+inf'), JSON_TYPE_INT), 
'4294967295');
+    is($bigcjson->encode(Math::BigFloat->new('-inf'), JSON_TYPE_INT), 
'-2147483648');
+  } elsif ($Config{ivsize} == 8) {
+    is($bigcjson->encode(Math::BigFloat->new('+inf'), JSON_TYPE_INT), 
'18446744073709551615');
+    is($bigcjson->encode(Math::BigFloat->new('-inf'), JSON_TYPE_INT), 
'-9223372036854775808');
+  } else {
+    skip "unknown ivsize $Config{ivsize}", 2;
+  }
+}
+
+my $fltinf;
+if ($Config{nvtype} eq 'long double' && $Config{longdblkind} == 3) {
+  $fltinf = '1.18973149535723177e+4932';
+} elsif ($Config{nvtype} eq 'double' && $Config{nvsize} == 8) {
+  $fltinf = '1.79769313486232e+308';
+}
+is($cjson->encode(   int("NaN"), JSON_TYPE_FLOAT), '0.0');
+is($cjson->encode(        'NaN', JSON_TYPE_FLOAT), '0.0');
+SKIP: {
+  skip "unknown nvtype $Config{nvtype}, longdblkind $Config{longdblkind}", 6
+      unless $fltinf;
+  is($cjson->encode(  int( 'Inf'), JSON_TYPE_FLOAT), ($] >= 5.008 && $] < 
5.008008) ? '0.0' :  $fltinf);
+  is($cjson->encode(  int('-Inf'), JSON_TYPE_FLOAT), ($] >= 5.008 && $] < 
5.008008) ? '0.0' : "-$fltinf");
+  is($cjson->encode(        'Inf', JSON_TYPE_FLOAT),  $fltinf);
+  is($cjson->encode(       '-Inf', JSON_TYPE_FLOAT), "-$fltinf");
+  is($cjson->encode(      9**9**9, JSON_TYPE_FLOAT),  $fltinf);
+  is($cjson->encode(     -9**9**9, JSON_TYPE_FLOAT), "-$fltinf");
+}
+
+SKIP: {
+  skip 'requires Math::BigFloat', 20 unless eval { require Math::BigFloat } or
+    !$fltinf;
+  skip 'too old', 20 if $] < 5.008;
+  is($bigcjson->encode(   int("NaN"), JSON_TYPE_FLOAT), '0.0');
+  is($bigcjson->encode(        'NaN', JSON_TYPE_FLOAT), '0.0');
+  is($bigcjson->encode(  int( 'Inf'), JSON_TYPE_FLOAT), ($] >= 5.008 && $] < 
5.008008) ? '0.0' :  $fltinf);
+  is($bigcjson->encode(  int('-Inf'), JSON_TYPE_FLOAT), ($] >= 5.008 && $] < 
5.008008) ? '0.0' : "-$fltinf");
+  is($bigcjson->encode(        'Inf', JSON_TYPE_FLOAT),  $fltinf);
+  is($bigcjson->encode(       '-Inf', JSON_TYPE_FLOAT), "-$fltinf");
+  is($bigcjson->encode(      9**9**9, JSON_TYPE_FLOAT),  $fltinf);
+  is($bigcjson->encode(     -9**9**9, JSON_TYPE_FLOAT), "-$fltinf");
+
+  # integer string values outside of range [IV_MIN, UV_MAX] with enabled bignum
+  is($bigcjson->encode('18446744073709551616', JSON_TYPE_FLOAT), 
'18446744073709551616.0');  #  2^64
+  is($bigcjson->encode('18446744073709551617', JSON_TYPE_FLOAT), 
'18446744073709551617.0');  #  2^64+1
+  is($bigcjson->encode('18446744073709551618', JSON_TYPE_FLOAT), 
'18446744073709551618.0');  #  2^64+2
+  is($bigcjson->encode('-9223372036854775809', JSON_TYPE_FLOAT), 
'-9223372036854775809.0');  # -2^63-1
+  is($bigcjson->encode('-9223372036854775810', JSON_TYPE_FLOAT), 
'-9223372036854775810.0');  # -2^63-2
+
+  # float string values outside of range [IV_MIN, UV_MAX] with enabled bignum
+  is($bigcjson->encode('18446744073709551616.5', JSON_TYPE_FLOAT), 
'18446744073709551616.5');  #  2^64
+  is($bigcjson->encode('18446744073709551617.5', JSON_TYPE_FLOAT), 
'18446744073709551617.5');  #  2^64+1
+  is($bigcjson->encode('18446744073709551618.5', JSON_TYPE_FLOAT), 
'18446744073709551618.5');  #  2^64+2
+  is($bigcjson->encode('-9223372036854775809.5', JSON_TYPE_FLOAT), 
'-9223372036854775809.5');  # -2^63-1
+  is($bigcjson->encode('-9223372036854775810.5', JSON_TYPE_FLOAT), 
'-9223372036854775810.5');  # -2^63-2
+  is($bigcjson->encode(  '7.37869762948382e+19', JSON_TYPE_FLOAT), 
'73786976294838200000.0');
+  is($bigcjson->encode('7.37869762948382123456789e+19', JSON_TYPE_FLOAT), 
'73786976294838212345.6789');
+}
+
+SKIP: {
+  skip 'requires Math::BigInt', 8 unless eval { require Math::BigInt };
+  skip 'requires Math::BigFloat', 8 unless eval { require Math::BigFloat };
+  skip "unknown nvtype $Config{nvtype}, longdblkind $Config{longdblkind}", 8
+      unless $fltinf;
+  skip 'too old', 8 if $] < 5.008;
+
+  # Math::BigInt values with enabled bignum
+  is($bigcjson->encode(Math::BigInt->new('18446744073709551616'), 
JSON_TYPE_FLOAT), '18446744073709551616.0');  #  2^64
+  is($bigcjson->encode(Math::BigInt->new('18446744073709551617'), 
JSON_TYPE_FLOAT), '18446744073709551617.0');  #  2^64+1
+  is($bigcjson->encode(Math::BigInt->new('18446744073709551618'), 
JSON_TYPE_FLOAT), '18446744073709551618.0');  #  2^64+2
+  is($bigcjson->encode(Math::BigInt->new('-9223372036854775809'), 
JSON_TYPE_FLOAT), '-9223372036854775809.0');  # -2^63-1
+  is($bigcjson->encode(Math::BigInt->new('-9223372036854775810'), 
JSON_TYPE_FLOAT), '-9223372036854775810.0');  # -2^63-2
+
+  is($bigcjson->encode(Math::BigInt->new('NaN'), JSON_TYPE_FLOAT), '0.0');
+  is($bigcjson->encode(Math::BigInt->new('+inf'), JSON_TYPE_FLOAT), $fltinf);
+  is($bigcjson->encode(Math::BigInt->new('-inf'), JSON_TYPE_FLOAT), 
"-$fltinf");
+}
+
+SKIP: {
+  skip 'requires Math::BigFloat', 8 unless eval { require Math::BigFloat };
+  skip "unknown nvtype $Config{nvtype}, longdblkind $Config{longdblkind}", 8
+      unless $fltinf;
+  skip 'too old', 8 if $] < 5.008;
+
+  # Math::BigFloat values with enabled bignum
+  is($bigcjson->encode(Math::BigFloat->new('18446744073709551616.5'), 
JSON_TYPE_FLOAT), '18446744073709551616.5');  #  2^64
+  is($bigcjson->encode(Math::BigFloat->new('18446744073709551617.5'), 
JSON_TYPE_FLOAT), '18446744073709551617.5');  #  2^64+1
+  is($bigcjson->encode(Math::BigFloat->new('18446744073709551618.5'), 
JSON_TYPE_FLOAT), '18446744073709551618.5');  #  2^64+2
+  is($bigcjson->encode(Math::BigFloat->new('-9223372036854775809.5'), 
JSON_TYPE_FLOAT), '-9223372036854775809.5');  # -2^63-1
+  is($bigcjson->encode(Math::BigFloat->new('-9223372036854775810.5'), 
JSON_TYPE_FLOAT), '-9223372036854775810.5');  # -2^63-2
+
+  is($bigcjson->encode(Math::BigFloat->new('NaN'), JSON_TYPE_FLOAT), '0.0');
+  is($bigcjson->encode(Math::BigFloat->new('+inf'), JSON_TYPE_FLOAT), $fltinf);
+  is($bigcjson->encode(Math::BigFloat->new('-inf'), JSON_TYPE_FLOAT), 
"-$fltinf");
+}
+
+SKIP: {
+  skip 'requires Math::BigInt', 1 unless eval { require Math::BigInt };
+  my $stringified_int = '-9223372036854775810';
+  do { my $temp = $stringified_int + 10 };
+  is($bigcjson->encode($stringified_int, JSON_TYPE_INT), 
'-9223372036854775810');
+}
 
 is(encode_json([10, "10", 10.25], [JSON_TYPE_INT, JSON_TYPE_INT, 
JSON_TYPE_STRING]), '[10,10,"10.25"]');
 is(encode_json([10, "10", 10.25], json_type_arrayof(JSON_TYPE_INT)), 
'[10,10,10]');
@@ -451,3 +609,6 @@
 
 ok(!defined eval { $cjson->encode({ key => 1 }, { key => undef }) });
 like($@, qr/type for '1' was not specified/);
+
+ok(!defined eval { $cjson->encode(bless({}, 'Object'), JSON_TYPE_STRING) });
+like($@, qr/encountered object.*but neither allow_blessed, convert_blessed nor 
allow_tags settings are enabled/);


Reply via email to