Hello community,

here is the log from the commit of package perl-JSON-XS for openSUSE:Factory 
checked in at 2018-12-12 17:27:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-JSON-XS (Old)
 and      /work/SRC/openSUSE:Factory/.perl-JSON-XS.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-JSON-XS"

Wed Dec 12 17:27:12 2018 rev:21 rq:655789 version:4.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-JSON-XS/perl-JSON-XS.changes        
2017-09-04 12:36:37.676933521 +0200
+++ /work/SRC/openSUSE:Factory/.perl-JSON-XS.new.28833/perl-JSON-XS.changes     
2018-12-12 17:27:15.414970329 +0100
@@ -1,0 +2,6 @@
+Thu Dec  6 15:47:56 UTC 2018 - Stephan Kulow <co...@suse.com>
+
+- updated to 4.0
+   see /usr/share/doc/packages/perl-JSON-XS/Changes
+
+-------------------------------------------------------------------

Old:
----
  JSON-XS-3.04.tar.gz

New:
----
  JSON-XS-4.0.tar.gz

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

Other differences:
------------------
++++++ perl-JSON-XS.spec ++++++
--- /var/tmp/diff_new_pack.0LjaqV/_old  2018-12-12 17:27:16.050969521 +0100
+++ /var/tmp/diff_new_pack.0LjaqV/_new  2018-12-12 17:27:16.050969521 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package perl-JSON-XS
 #
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,19 +12,18 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 Name:           perl-JSON-XS
-Version:        3.04
+Version:        4.0
 Release:        0
-#Upstream: CHECK(GPL-1.0+ or Artistic-1.0)
 %define cpan_name JSON-XS
 Summary:        JSON serialising/deserialising, done correctly and fast
-License:        Artistic-1.0 or GPL-1.0+
+License:        Artistic-1.0 OR GPL-1.0-or-later
 Group:          Development/Libraries/Perl
-Url:            http://search.cpan.org/dist/JSON-XS/
+Url:            https://metacpan.org/release/%{cpan_name}
 Source0:        
https://cpan.metacpan.org/authors/id/M/ML/MLEHMANN/%{cpan_name}-%{version}.tar.gz
 Source1:        cpanspec.yml
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -42,20 +41,6 @@
 primary goal is to be _correct_ and its secondary goal is to be _fast_. To
 reach the latter goal it was written in C.
 
-Beginning with version 2.0 of the JSON module, when both JSON and JSON::XS
-are installed, then JSON will fall back on JSON::XS (this can be
-overridden) with no overhead due to emulation (by inheriting constructor
-and methods). If JSON::XS is not available, it will fall back to the
-compatible JSON::PP module as backend, so using JSON instead of JSON::XS
-gives you a portable JSON API that can be fast when you need it and doesn't
-require a C compiler when that is a problem.
-
-As this is the n-th-something JSON module on CPAN, what was the reason to
-write yet another JSON module? While it seems there are many JSON modules,
-none of them correctly handle all corner cases, and in most cases their
-maintainers are unresponsive, gone missing, or not listening to bug reports
-for other reasons.
-
 See MAPPING, below, on how JSON::XS maps perl values to JSON values and
 vice versa.
 
@@ -64,11 +49,11 @@
 find . -type f ! -name \*.pl -print0 | xargs -0 chmod 644
 
 %build
-%{__perl} Makefile.PL INSTALLDIRS=vendor OPTIMIZE="%{optflags}"
-%{__make} %{?_smp_mflags}
+perl Makefile.PL INSTALLDIRS=vendor OPTIMIZE="%{optflags}"
+make %{?_smp_mflags}
 
 %check
-%{__make} test
+make test
 
 %install
 %perl_make_install

++++++ JSON-XS-3.04.tar.gz -> JSON-XS-4.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/JSON-XS-3.04/Changes new/JSON-XS-4.0/Changes
--- old/JSON-XS-3.04/Changes    2017-08-17 04:31:27.000000000 +0200
+++ new/JSON-XS-4.0/Changes     2018-11-19 11:26:51.000000000 +0100
@@ -1,13 +1,27 @@
 Revision history for Perl extension JSON::XS
 
-TODO: maybe detetc and croak on more invalid inputs (e.g. +-inf/nan)
+TODO: maybe detect and croak on more invalid inputs (e.g. +-inf/nan)
 TODO: maybe avoid the reblessing and better support readonly objects.
-TODO: http://stevehanov.ca/blog/index.php?id=104 compression
 TODO: how to cope with tagged values and standard json decoders
 TODO: investigate magic (Eric Brine)
-TODO: rfc7464
-TODO: Victor Efimov
-TODO: move json_xs to types::serialiser
+TODO: [PATCH] Types::Serialiser: Inline true(), false() and error() functions
+
+4.0  Fri Nov 16 00:06:54 CET 2018
+       - 4.0 pre-release, do not use other than for testing.
+       - SECURITY IMPLICATION: this release enables allow_nonref by default
+          for compatibnility with RFC 7159 and newer. See "old" vs. "new"
+          JSON under SECURITY CONSIDERATIONS.
+        - reworked the "old" vs. "new" JSON section.
+        - add ->boolean_values to provide the values to which booleans
+          decode (requested by Aristotle Pagaltzis).
+        - decode would wrongly accept ASCII NUL characters instead of
+          reporting them as trailing garbage.
+        - work around what smells like a perl bug w.r.t. exceptions
+          thrown in callbacks.
+        - incremental parser now more or less respects allow_nonref.
+       - json_xs json-pretty now enables canonical mode.
+        - add documentation section about I-JSON.
+        - minor documentation fixes/updates.
 
 3.04 Thu Aug 17 04:30:47 CEST 2017
        - change exponential realloc algorithm on encoding and string decoding 
to be
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/JSON-XS-3.04/META.json new/JSON-XS-4.0/META.json
--- old/JSON-XS-3.04/META.json  2017-08-17 05:47:47.000000000 +0200
+++ new/JSON-XS-4.0/META.json   2018-11-19 11:27:09.000000000 +0100
@@ -4,7 +4,7 @@
       "unknown"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "ExtUtils::MakeMaker version 7.3, CPAN::Meta::Converter 
version 2.150010",
+   "generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter 
version 2.150010",
    "license" : [
       "unknown"
    ],
@@ -39,6 +39,6 @@
       }
    },
    "release_status" : "stable",
-   "version" : 3.04,
+   "version" : "4.0",
    "x_serialization_backend" : "JSON::PP version 2.27300"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/JSON-XS-3.04/META.yml new/JSON-XS-4.0/META.yml
--- old/JSON-XS-3.04/META.yml   2017-08-17 05:47:47.000000000 +0200
+++ new/JSON-XS-4.0/META.yml    2018-11-19 11:27:09.000000000 +0100
@@ -8,7 +8,7 @@
   Canary::Stability: '0'
   ExtUtils::MakeMaker: '6.52'
 dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 7.3, CPAN::Meta::Converter version 
2.150010'
+generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 
2.150010'
 license: unknown
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -21,5 +21,5 @@
 requires:
   Types::Serialiser: '0'
   common::sense: '0'
-version: 3.04
+version: '4.0'
 x_serialization_backend: 'CPAN::Meta::YAML version 0.012'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/JSON-XS-3.04/README new/JSON-XS-4.0/README
--- old/JSON-XS-3.04/README     2017-08-17 05:47:47.000000000 +0200
+++ new/JSON-XS-4.0/README      2018-11-19 11:27:10.000000000 +0100
@@ -32,20 +32,6 @@
     primary goal is to be *correct* and its secondary goal is to be *fast*.
     To reach the latter goal it was written in C.
 
-    Beginning with version 2.0 of the JSON module, when both JSON and
-    JSON::XS are installed, then JSON will fall back on JSON::XS (this can
-    be overridden) with no overhead due to emulation (by inheriting
-    constructor and methods). If JSON::XS is not available, it will fall
-    back to the compatible JSON::PP module as backend, so using JSON instead
-    of JSON::XS gives you a portable JSON API that can be fast when you need
-    it and doesn't require a C compiler when that is a problem.
-
-    As this is the n-th-something JSON module on CPAN, what was the reason
-    to write yet another JSON module? While it seems there are many JSON
-    modules, none of them correctly handle all corner cases, and in most
-    cases their maintainers are unresponsive, gone missing, or not listening
-    to bug reports for other reasons.
-
     See MAPPING, below, on how JSON::XS maps perl values to JSON values and
     vice versa.
 
@@ -105,8 +91,8 @@
         Except being faster.
 
     $perl_scalar = decode_json $json_text
-        The opposite of "encode_json": expects an UTF-8 (binary) string and
-        tries to parse that as an UTF-8 encoded JSON text, returning the
+        The opposite of "encode_json": expects a UTF-8 (binary) string and
+        tries to parse that as a UTF-8 encoded JSON text, returning the
         resulting reference. Croaks on error.
 
         This function call is functionally identical to:
@@ -160,8 +146,9 @@
 
     $json = new JSON::XS
         Creates a new JSON::XS object that can be used to de/encode JSON
-        strings. All boolean flags described below are by default
-        *disabled*.
+        strings. All boolean flags described below are by default *disabled*
+        (with the exception of "allow_nonref", which defaults to *enabled*
+        since version 4.0).
 
         The mutators for flags all return the JSON object again and thus
         calls can be chained:
@@ -227,7 +214,7 @@
     $enabled = $json->get_utf8
         If $enable is true (or missing), then the "encode" method will
         encode the JSON result into UTF-8, as required by many protocols,
-        while the "decode" method expects to be handled an UTF-8-encoded
+        while the "decode" method expects to be handed a UTF-8-encoded
         string. Please note that UTF-8-encoded strings do not contain any
         characters outside the range 0..255, they are thus useful for
         bytewise/binary I/O. In future versions, enabling this option might
@@ -316,7 +303,7 @@
     $enabled = $json->get_relaxed
         If $enable is true (or missing), then "decode" will accept some
         extensions to normal JSON syntax (see below). "encode" will not be
-        affected in anyway. *Be aware that this option makes you accept
+        affected in any way. *Be aware that this option makes you accept
         invalid JSON texts as if they were valid!*. I suggest only to use
         this option to parse application-specific files written by humans
         (configuration files, resource files etc.)
@@ -387,6 +374,10 @@
 
     $json = $json->allow_nonref ([$enable])
     $enabled = $json->get_allow_nonref
+        Unlike other boolean options, this opotion is enabled by default
+        beginning with version 4.0. See "SECURITY CONSIDERATIONS" for the
+        gory details.
+
         If $enable is true (or missing), then the "encode" method can
         convert a non-reference into its corresponding string, number or
         null JSON value, which is an extension to RFC4627. Likewise,
@@ -397,11 +388,11 @@
         object or array. Likewise, "decode" will croak if given something
         that is not a JSON object or array.
 
-        Example, encode a Perl scalar as JSON value with enabled
-        "allow_nonref", resulting in an invalid JSON text:
+        Example, encode a Perl scalar as JSON value without enabled
+        "allow_nonref", resulting in an error:
 
-           JSON::XS->new->allow_nonref->encode ("Hello, World!")
-           => "Hello, World!"
+           JSON::XS->new->allow_nonref (0)->encode ("Hello, World!")
+           => hash- or arrayref expected...
 
     $json = $json->allow_unknown ([$enable])
     $enabled = $json->get_allow_unknown
@@ -457,7 +448,7 @@
         This setting has no effect on "decode".
 
     $json = $json->allow_tags ([$enable])
-    $enabled = $json->allow_tags
+    $enabled = $json->get_allow_tags
         See "OBJECT SERIALISATION" for details.
 
         If $enable is true (or missing), then "encode", upon encountering a
@@ -473,15 +464,32 @@
         this type of conversion, and tagged JSON values will cause a parse
         error in "decode", as if tags were not part of the grammar.
 
+    $json->boolean_values ([$false, $true])
+    ($false, $true) = $json->get_boolean_values
+        By default, JSON booleans will be decoded as overloaded
+        $Types::Serialiser::false and $Types::Serialiser::true objects.
+
+        With this method you can specify your own boolean values for
+        decoding - on decode, JSON "false" will be decoded as a copy of
+        $false, and JSON "true" will be decoded as $true ("copy" here is the
+        same thing as assigning a value to another variable, i.e. "$copy =
+        $false").
+
+        Calling this method without any arguments will reset the booleans to
+        their default values.
+
+        "get_boolean_values" will return both $false and $true values, or
+        the empty list when they are set to the default.
+
     $json = $json->filter_json_object ([$coderef->($hashref)])
         When $coderef is specified, it will be called from "decode" each
         time it decodes a JSON object. The only argument is a reference to
-        the newly-created hash. If the code references returns a single
-        scalar (which need not be a reference), this value (i.e. a copy of
-        that scalar to avoid aliasing) is inserted into the deserialised
-        data structure. If it returns an empty list (NOTE: *not* "undef",
-        which is a valid scalar), the original deserialised hash will be
-        inserted. This setting can slow down decoding considerably.
+        the newly-created hash. If the code reference returns a single
+        scalar (which need not be a reference), this value (or rather a copy
+        of it) is inserted into the deserialised data structure. If it
+        returns an empty list (NOTE: *not* "undef", which is a valid
+        scalar), the original deserialised hash will be inserted. This
+        setting can slow down decoding considerably.
 
         When $coderef is omitted or undefined, any existing callback will be
         removed and "decode" will not change the deserialised hash in any
@@ -726,16 +734,19 @@
         parser after each successful decode.
 
   LIMITATIONS
-    All options that affect decoding are supported, except "allow_nonref".
-    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 1 a single JSON number, or is it simply the
-    start of 12? Or is 12 a single JSON number, or the concatenation of 1
-    and 2? In neither case you can tell, and this is why JSON::XS takes the
-    conservative route and disallows this case.
+    The incremental parser is a non-exact parser: it works by gathering as
+    much text as possible that *could* be a valid JSON text, followed by
+    trying to decode it.
+
+    That means it sometimes needs to read more data than strictly necessary
+    to diagnose an invalid JSON text. For example, after parsing the
+    following fragment, the parser *could* stop with an error, as this
+    fragment *cannot* be the beginning of a valid JSON text:
+
+       [,
+
+    In reality, hopwever, the parser might continue to read data until a
+    length limit is exceeded or it finds a closing bracket.
 
   EXAMPLES
     Some examples will make all this clearer. First, a simple example that
@@ -1178,8 +1189,8 @@
         does not allow that.
 
         The "utf8" flag therefore switches between two modes: disabled means
-        you will get a Unicode string in Perl, enabled means you get an
-        UTF-8 encoded octet/binary string in Perl.
+        you will get a Unicode string in Perl, enabled means you get a UTF-8
+        encoded octet/binary string in Perl.
 
     "latin1" or "ascii" flags enabled
         With "latin1" (or "ascii") enabled, "encode" will escape characters
@@ -1445,44 +1456,94 @@
     deal with it, as major browser developers care only for features, not
     about getting security right).
 
-"OLD" VS. "NEW" JSON (RFC 4627 VS. RFC 7159)
-    TL;DR: Due to security concerns, JSON::XS will not allow scalar data in
-    JSON texts by default - you need to create your own JSON::XS object and
-    enable "allow_nonref":
-
-       my $json = JSON::XS->new->allow_nonref;
-
-       $text = $json->encode ($data);
-       $data = $json->decode ($text);
-
-    The long version: JSON being an important and supposedly stable format,
-    the IETF standardised it as RFC 4627 in 2006. Unfortunately, the
-    inventor of JSON, Dougles Crockford, unilaterally changed the definition
-    of JSON in javascript. Rather than create a fork, the IETF decided to
-    standardise the new syntax (apparently, so Iw as told, without finding
-    it very amusing).
-
-    The biggest difference between thed original JSON and the new JSON is
-    that the new JSON supports scalars (anything other than arrays and
-    objects) at the toplevel of a JSON text. While this is strictly
-    backwards compatible to older versions, it breaks a number of protocols
-    that relied on sending JSON back-to-back, and is a minor security
-    concern.
-
-    For example, imagine you have two banks communicating, and on one side,
-    trhe JSON coder gets upgraded. Two messages, such as 10 and 1000 might
-    then be confused to mean 101000, something that couldn't happen in the
-    original JSON, because niether of these messages would be valid JSON.
-
-    If one side accepts these messages, then an upgrade in the coder on
-    either side could result in this becoming exploitable.
-
-    This module has always allowed these messages as an optional extension,
-    by default disabled. The security concerns are the reason why the
-    default is still disabled, but future versions might/will likely upgrade
-    to the newer RFC as default format, so you are advised to check your
-    implementation and/or override the default with "->allow_nonref (0)" to
-    ensure that future versions are safe.
+  "OLD" VS. "NEW" JSON (RFC4627 VS. RFC7159)
+    JSON originally required JSON texts to represent an array or object -
+    scalar values were explicitly not allowed. This has changed, and
+    versions of JSON::XS beginning with 4.0 reflect this by allowing scalar
+    values by default.
+
+    One reason why one might not want this is that this removes a
+    fundamental property of JSON texts, namely that they are self-delimited
+    and self-contained, or in other words, you could take any number of
+    "old" JSON texts and paste them together, and the result would be
+    unambiguously parseable:
+
+       [1,3]{"k":5}[][null] # four JSON texts, without doubt
+
+    By allowing scalars, this property is lost: in the following example, is
+    this one JSON text (the number 12) or two JSON texts (the numbers 1 and
+    2):
+
+       12    # could be 12, or 1 and 2
+
+    Another lost property of "old" JSON is that no lookahead is required to
+    know the end of a JSON text, i.e. the JSON text definitely ended at the
+    last "]" or "}" character, there was no need to read extra characters.
+
+    For example, a viable network protocol with "old" JSON was to simply
+    exchange JSON texts without delimiter. For "new" JSON, you have to use a
+    suitable delimiter (such as a newline) after every JSON text or ensure
+    you never encode/decode scalar values.
+
+    Most protocols do work by only transferring arrays or objects, and the
+    easiest way to avoid problems with the "new" JSON definition is to
+    explicitly disallow scalar values in your encoder and decoder:
+
+       $json_coder = JSON::XS->new->allow_nonref (0)
+
+    This is a somewhat unhappy situation, and the blame can fully be put on
+    JSON's inmventor, Douglas Crockford, who unilaterally changed the format
+    in 2006 without consulting the IETF, forcing the IETF to either fork the
+    format or go with it (as I was told, the IETF wasn't amused).
+
+RELATIONSHIP WITH I-JSON
+    JSON is a somewhat sloppily-defined format - it carries around obvious
+    Javascript baggage, such as not really defining number range, probably
+    because Javascript only has one type of numbers: IEEE 64 bit floats
+    ("binary64").
+
+    For this reaosn, RFC7493 defines "Internet JSON", which is a restricted
+    subset of JSON that is supposedly more interoperable on the internet.
+
+    While "JSON::XS" does not offer specific support for I-JSON, it of
+    course accepts valid I-JSON and by default implements some of the
+    limitations of I-JSON, such as parsing numbers as perl numbers, which
+    are usually a superset of binary64 numbers.
+
+    To generate I-JSON, follow these rules:
+
+    *   always generate UTF-8
+
+        I-JSON must be encoded in UTF-8, the default for "encode_json".
+
+    *   numbers should be within IEEE 754 binary64 range
+
+        Basically all existing perl installations use binary64 to represent
+        floating point numbers, so all you need to do is to avoid large
+        integers.
+
+    *   objects must not have duplicate keys
+
+        This is trivially done, as "JSON::XS" does not allow duplicate keys.
+
+    *   do not generate scalar JSON texts, use "->allow_nonref (0)"
+
+        I-JSON strongly requests you to only encode arrays and objects into
+        JSON.
+
+    *   times should be strings in ISO 8601 format
+
+        There are a myriad of modules on CPAN dealing with ISO 8601 - search
+        for "ISO8601" on CPAN and use one.
+
+    *   encode binary data as base64
+
+        While it's tempting to just dump binary data as a string (and let
+        "JSON::XS" do the escaping), for I-JSON, it's *recommended* to
+        encode binary data as base64.
+
+    There are some other considerations - read RFC7493 for the details if
+    interested.
 
 INTEROPERABILITY WITH OTHER MODULES
     "JSON::XS" uses the Types::Serialiser module to provide boolean
@@ -1549,26 +1610,10 @@
     Again, this has some limitations - the magic string must not be encoded
     with character escapes, and the constructor arguments must be non-empty.
 
-RFC7159
-    Since this module was written, Google has written a new JSON RFC, RFC
-    7159 (and RFC7158). Unfortunately, this RFC breaks compatibility with
-    both the original JSON specification on www.json.org and RFC4627.
-
-    As far as I can see, you can get partial compatibility when parsing by
-    using "->allow_nonref". However, consider the security implications of
-    doing so.
-
-    I haven't decided yet when to break compatibility with RFC4627 by
-    default (and potentially leave applications insecure) and change the
-    default to follow RFC7159, but application authors are well advised to
-    call "->allow_nonref(0)" even if this is the current default, if they
-    cannot handle non-reference values, in preparation for the day when the
-    default will change.
-
 (I-)THREADS
     This module is *not* guaranteed to be ithread (or MULTIPLICITY-) safe
     and there are no plans to change this. Note that perl's builtin
-    so-called theeads/ithreads are officially deprecated and should not be
+    so-called threads/ithreads are officially deprecated and should not be
     used.
 
 THE PERILS OF SETLOCALE
@@ -1587,6 +1632,30 @@
     actually needs it (avoiding stringification of numbers), and restore it
     afterwards.
 
+SOME HISTORY
+    At the time this module was created there already were a number of JSON
+    modules available on CPAN, so what was the reason to write yet another
+    JSON module? While it seems there are many JSON modules, none of them
+    correctly handled all corner cases, and in most cases their maintainers
+    are unresponsive, gone missing, or not listening to bug reports for
+    other reasons.
+
+    Beginning with version 2.0 of the JSON module, when both JSON and
+    JSON::XS are installed, then JSON will fall back on JSON::XS (this can
+    be overridden) with no overhead due to emulation (by inheriting
+    constructor and methods). If JSON::XS is not available, it will fall
+    back to the compatible JSON::PP module as backend, so using JSON instead
+    of JSON::XS gives you a portable JSON API that can be fast when you need
+    it and doesn't require a C compiler when that is a problem.
+
+    Somewhere around version 3, this module was forked into
+    "Cpanel::JSON::XS", because its maintainer had serious trouble
+    understanding JSON and insisted on a fork with many bugs "fixed" that
+    weren't actually bugs, while spreading FUD about this module without
+    actually giving any details on his accusations. You be the judge, but in
+    my personal opinion, if you want quality, you will stay away from
+    dangerous forks like that.
+
 BUGS
     While the goal of this module is to be correct, that unfortunately does
     not mean it's bug-free, only that I think its design is bug-free. If you
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/JSON-XS-3.04/XS.pm new/JSON-XS-4.0/XS.pm
--- old/JSON-XS-3.04/XS.pm      2017-08-17 04:31:35.000000000 +0200
+++ new/JSON-XS-4.0/XS.pm       2018-11-19 11:26:55.000000000 +0100
@@ -37,26 +37,12 @@
 primary goal is to be I<correct> and its secondary goal is to be
 I<fast>. To reach the latter goal it was written in C.
 
-Beginning with version 2.0 of the JSON module, when both JSON and
-JSON::XS are installed, then JSON will fall back on JSON::XS (this can be
-overridden) with no overhead due to emulation (by inheriting constructor
-and methods). If JSON::XS is not available, it will fall back to the
-compatible JSON::PP module as backend, so using JSON instead of JSON::XS
-gives you a portable JSON API that can be fast when you need it and
-doesn't require a C compiler when that is a problem.
-
-As this is the n-th-something JSON module on CPAN, what was the reason
-to write yet another JSON module? While it seems there are many JSON
-modules, none of them correctly handle all corner cases, and in most cases
-their maintainers are unresponsive, gone missing, or not listening to bug
-reports for other reasons.
-
 See MAPPING, below, on how JSON::XS maps perl values to JSON values and
 vice versa.
 
 =head2 FEATURES
 
-=over 4
+=over
 
 =item * correct Unicode handling
 
@@ -103,7 +89,7 @@
 
 use common::sense;
 
-our $VERSION = 3.04;
+our $VERSION = '4.0';
 our @ISA = qw(Exporter);
 
 our @EXPORT = qw(encode_json decode_json);
@@ -118,7 +104,7 @@
 The following convenience methods are provided by this module. They are
 exported by default:
 
-=over 4
+=over
 
 =item $json_text = encode_json $perl_scalar
 
@@ -133,8 +119,8 @@
 
 =item $perl_scalar = decode_json $json_text
 
-The opposite of C<encode_json>: expects an UTF-8 (binary) string and tries
-to parse that as an UTF-8 encoded JSON text, returning the resulting
+The opposite of C<encode_json>: expects a UTF-8 (binary) string and tries
+to parse that as a UTF-8 encoded JSON text, returning the resulting
 reference. Croaks on error.
 
 This function call is functionally identical to:
@@ -151,7 +137,7 @@
 Since this often leads to confusion, here are a few very clear words on
 how Unicode works in Perl, modulo bugs.
 
-=over 4
+=over
 
 =item 1. Perl strings can store characters with ordinal values > 255.
 
@@ -199,12 +185,14 @@
 The object oriented interface lets you configure your own encoding or
 decoding style, within the limits of supported formats.
 
-=over 4
+=over
 
 =item $json = new JSON::XS
 
 Creates a new JSON::XS object that can be used to de/encode JSON
-strings. All boolean flags described below are by default I<disabled>.
+strings. All boolean flags described below are by default I<disabled>
+(with the exception of C<allow_nonref>, which defaults to I<enabled> since
+version C<4.0>).
 
 The mutators for flags all return the JSON object again and thus calls can
 be chained:
@@ -272,7 +260,7 @@
 
 If C<$enable> is true (or missing), then the C<encode> method will encode
 the JSON result into UTF-8, as required by many protocols, while the
-C<decode> method expects to be handled an UTF-8-encoded string.  Please
+C<decode> method expects to be handed a UTF-8-encoded string.  Please
 note that UTF-8-encoded strings do not contain any characters outside the
 range C<0..255>, they are thus useful for bytewise/binary I/O. In future
 versions, enabling this option might enable autodetection of the UTF-16
@@ -367,7 +355,7 @@
 
 If C<$enable> is true (or missing), then C<decode> will accept some
 extensions to normal JSON syntax (see below). C<encode> will not be
-affected in anyway. I<Be aware that this option makes you accept invalid
+affected in any way. I<Be aware that this option makes you accept invalid
 JSON texts as if they were valid!>. I suggest only to use this option to
 parse application-specific files written by humans (configuration files,
 resource files etc.)
@@ -377,7 +365,7 @@
 
 Currently accepted extensions are:
 
-=over 4
+=over
 
 =item * list items can have an end-comma
 
@@ -443,6 +431,9 @@
 
 =item $enabled = $json->get_allow_nonref
 
+Unlike other boolean options, this opotion is enabled by default beginning
+with version C<4.0>. See L<SECURITY CONSIDERATIONS> for the gory details.
+
 If C<$enable> is true (or missing), then the C<encode> method can convert a
 non-reference into its corresponding string, number or null JSON value,
 which is an extension to RFC4627. Likewise, C<decode> will accept those JSON
@@ -453,11 +444,11 @@
 or array. Likewise, C<decode> will croak if given something that is not a
 JSON object or array.
 
-Example, encode a Perl scalar as JSON value with enabled C<allow_nonref>,
-resulting in an invalid JSON text:
+Example, encode a Perl scalar as JSON value without enabled C<allow_nonref>,
+resulting in an error:
 
-   JSON::XS->new->allow_nonref->encode ("Hello, World!")
-   => "Hello, World!"
+   JSON::XS->new->allow_nonref (0)->encode ("Hello, World!")
+   => hash- or arrayref expected...
 
 =item $json = $json->allow_unknown ([$enable])
 
@@ -517,7 +508,7 @@
 
 =item $json = $json->allow_tags ([$enable])
 
-=item $enabled = $json->allow_tags
+=item $enabled = $json->get_allow_tags
 
 See L<OBJECT SERIALISATION> for details.
 
@@ -533,16 +524,34 @@
 this type of conversion, and tagged JSON values will cause a parse error
 in C<decode>, as if tags were not part of the grammar.
 
+=item $json->boolean_values ([$false, $true])
+
+=item ($false,  $true) = $json->get_boolean_values
+
+By default, JSON booleans will be decoded as overloaded
+C<$Types::Serialiser::false> and C<$Types::Serialiser::true> objects.
+
+With this method you can specify your own boolean values for decoding -
+on decode, JSON C<false> will be decoded as a copy of C<$false>, and JSON
+C<true> will be decoded as C<$true> ("copy" here is the same thing as
+assigning a value to another variable, i.e. C<$copy = $false>).
+
+Calling this method without any arguments will reset the booleans
+to their default values.
+
+C<get_boolean_values> will return both C<$false> and C<$true> values, or
+the empty list when they are set to the default.
+
 =item $json = $json->filter_json_object ([$coderef->($hashref)])
 
 When C<$coderef> is specified, it will be called from C<decode> each
-time it decodes a JSON object. The only argument is a reference to the
-newly-created hash. If the code references returns a single scalar (which
-need not be a reference), this value (i.e. a copy of that scalar to avoid
-aliasing) is inserted into the deserialised data structure. If it returns
-an empty list (NOTE: I<not> C<undef>, which is a valid scalar), the
-original deserialised hash will be inserted. This setting can slow down
-decoding considerably.
+time it decodes a JSON object. The only argument is a reference to
+the newly-created hash. If the code reference returns a single scalar
+(which need not be a reference), this value (or rather a copy of it) is
+inserted into the deserialised data structure. If it returns an empty
+list (NOTE: I<not> C<undef>, which is a valid scalar), the original
+deserialised hash will be inserted. This setting can slow down decoding
+considerably.
 
 When C<$coderef> is omitted or undefined, any existing callback will
 be removed and C<decode> will not change the deserialised hash in any
@@ -726,7 +735,7 @@
 
 The following methods implement this incremental parser.
 
-=over 4
+=over
 
 =item [void, scalar or list context] = $json->incr_parse ([$string])
 
@@ -803,16 +812,19 @@
 
 =head2 LIMITATIONS
 
-All options that affect decoding are supported, except
-C<allow_nonref>. 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 JSON::XS
-takes the conservative route and disallows this case.
+The incremental parser is a non-exact parser: it works by gathering as
+much text as possible that I<could> be a valid JSON text, followed by
+trying to decode it.
+
+That means it sometimes needs to read more data than strictly necessary to
+diagnose an invalid JSON text. For example, after parsing the following
+fragment, the parser I<could> stop with an error, as this fragment
+I<cannot> be the beginning of a valid JSON text:
+
+   [,
+
+In reality, hopwever, the parser might continue to read data until a
+length limit is exceeded or it finds a closing bracket.
 
 =head2 EXAMPLES
 
@@ -966,7 +978,7 @@
 
 =head2 JSON -> PERL
 
-=over 4
+=over
 
 =item object
 
@@ -1044,7 +1056,7 @@
 truly typeless language, so we can only guess which JSON type is meant by
 a Perl value.
 
-=over 4
+=over
 
 =item hash references
 
@@ -1143,7 +1155,7 @@
 C<allow_blessed>, C<convert_blessed> and C<allow_tags> settings, which are
 used in this order:
 
-=over 4
+=over
 
 =item 1. C<allow_tags> is enabled and the object has a C<FREEZE> method.
 
@@ -1264,7 +1276,7 @@
 and ISO-8859-1 (= latin 1) and ASCII are both codesets I<and> encodings at
 the same time, which can be confusing.
 
-=over 4
+=over
 
 =item C<utf8> flag disabled
 
@@ -1291,7 +1303,7 @@
 that.
 
 The C<utf8> flag therefore switches between two modes: disabled means you
-will get a Unicode string in Perl, enabled means you get an UTF-8 encoded
+will get a Unicode string in Perl, enabled means you get a UTF-8 encoded
 octet/binary string in Perl.
 
 =item C<latin1> or C<ascii> flags enabled
@@ -1433,7 +1445,7 @@
 high that you will run into severe interoperability problems when you
 least expect it.
 
-=over 4
+=over
 
 =item (*)
 
@@ -1569,45 +1581,99 @@
 security right).
 
 
-=head1 "OLD" VS. "NEW" JSON (RFC 4627 VS. RFC 7159)
+=head2 "OLD" VS. "NEW" JSON (RFC4627 VS. RFC7159)
+
+JSON originally required JSON texts to represent an array or object -
+scalar values were explicitly not allowed. This has changed, and versions
+of JSON::XS beginning with C<4.0> reflect this by allowing scalar values
+by default.
+
+One reason why one might not want this is that this removes a fundamental
+property of JSON texts, namely that they are self-delimited and
+self-contained, or in other words, you could take any number of "old"
+JSON texts and paste them together, and the result would be unambiguously
+parseable:
+
+   [1,3]{"k":5}[][null] # four JSON texts, without doubt
+
+By allowing scalars, this property is lost: in the following example, is
+this one JSON text (the number 12) or two JSON texts (the numbers 1 and
+2):
+
+   12    # could be 12, or 1 and 2
+
+Another lost property of "old" JSON is that no lookahead is required to
+know the end of a JSON text, i.e. the JSON text definitely ended at the
+last C<]> or C<}> character, there was no need to read extra characters.
+
+For example, a viable network protocol with "old" JSON was to simply
+exchange JSON texts without delimiter. For "new" JSON, you have to use a
+suitable delimiter (such as a newline) after every JSON text or ensure you
+never encode/decode scalar values.
+
+Most protocols do work by only transferring arrays or objects, and the
+easiest way to avoid problems with the "new" JSON definition is to
+explicitly disallow scalar values in your encoder and decoder:
+
+   $json_coder = JSON::XS->new->allow_nonref (0)
+
+This is a somewhat unhappy situation, and the blame can fully be put on
+JSON's inmventor, Douglas Crockford, who unilaterally changed the format
+in 2006 without consulting the IETF, forcing the IETF to either fork the
+format or go with it (as I was told, the IETF wasn't amused).
+
+
+=head1 RELATIONSHIP WITH I-JSON
+
+JSON is a somewhat sloppily-defined format - it carries around obvious
+Javascript baggage, such as not really defining number range, probably
+because Javascript only has one type of numbers: IEEE 64 bit floats
+("binary64").
+
+For this reaosn, RFC7493 defines "Internet JSON", which is a restricted
+subset of JSON that is supposedly more interoperable on the internet.
 
-TL;DR: Due to security concerns, JSON::XS will not allow scalar data in
-JSON texts by default - you need to create your own JSON::XS object and
-enable C<allow_nonref>:
-
-
-   my $json = JSON::XS->new->allow_nonref;
-
-   $text = $json->encode ($data);
-   $data = $json->decode ($text);
-
-The long version: JSON being an important and supposedly stable format,
-the IETF standardised it as RFC 4627 in 2006. Unfortunately, the inventor
-of JSON, Dougles Crockford, unilaterally changed the definition of JSON in
-javascript. Rather than create a fork, the IETF decided to standardise the
-new syntax (apparently, so Iw as told, without finding it very amusing).
-
-The biggest difference between thed original JSON and the new JSON is that
-the new JSON supports scalars (anything other than arrays and objects) at
-the toplevel of a JSON text. While this is strictly backwards compatible
-to older versions, it breaks a number of protocols that relied on sending
-JSON back-to-back, and is a minor security concern.
-
-For example, imagine you have two banks communicating, and on one side,
-trhe JSON coder gets upgraded. Two messages, such as C<10> and C<1000>
-might then be confused to mean C<101000>, something that couldn't happen
-in the original JSON, because niether of these messages would be valid
-JSON.
-
-If one side accepts these messages, then an upgrade in the coder on either
-side could result in this becoming exploitable.
-
-This module has always allowed these messages as an optional extension, by
-default disabled. The security concerns are the reason why the default is
-still disabled, but future versions might/will likely upgrade to the newer
-RFC as default format, so you are advised to check your implementation
-and/or override the default with C<< ->allow_nonref (0) >> to ensure that
-future versions are safe.
+While C<JSON::XS> does not offer specific support for I-JSON, it of course
+accepts valid I-JSON and by default implements some of the limitations
+of I-JSON, such as parsing numbers as perl numbers, which are usually a
+superset of binary64 numbers.
+
+To generate I-JSON, follow these rules:
+
+=over
+
+=item * always generate UTF-8
+
+I-JSON must be encoded in UTF-8, the default for C<encode_json>.
+
+=item * numbers should be within IEEE 754 binary64 range
+
+Basically all existing perl installations use binary64 to represent
+floating point numbers, so all you need to do is to avoid large integers.
+
+=item * objects must not have duplicate keys
+
+This is trivially done, as C<JSON::XS> does not allow duplicate keys.
+
+=item * do not generate scalar JSON texts, use C<< ->allow_nonref (0) >>
+
+I-JSON strongly requests you to only encode arrays and objects into JSON.
+
+=item * times should be strings in ISO 8601 format
+
+There are a myriad of modules on CPAN dealing with ISO 8601 - search for
+C<ISO8601> on CPAN and use one.
+
+=item * encode binary data as base64
+
+While it's tempting to just dump binary data as a string (and let
+C<JSON::XS> do the escaping), for I-JSON, it's I<recommended> to encode
+binary data as base64.
+
+=back
+
+There are some other considerations - read RFC7493 for the details if
+interested.
 
 
 =head1 INTEROPERABILITY WITH OTHER MODULES
@@ -1680,29 +1746,11 @@
 with character escapes, and the constructor arguments must be non-empty.
 
 
-=head1 RFC7159
-
-Since this module was written, Google has written a new JSON RFC, RFC 7159
-(and RFC7158). Unfortunately, this RFC breaks compatibility with both the
-original JSON specification on www.json.org and RFC4627.
-
-As far as I can see, you can get partial compatibility when parsing by
-using C<< ->allow_nonref >>. However, consider the security implications
-of doing so.
-
-I haven't decided yet when to break compatibility with RFC4627 by default
-(and potentially leave applications insecure) and change the default to
-follow RFC7159, but application authors are well advised to call C<<
-->allow_nonref(0) >> even if this is the current default, if they cannot
-handle non-reference values, in preparation for the day when the default
-will change.
-
-
 =head1 (I-)THREADS
 
 This module is I<not> guaranteed to be ithread (or MULTIPLICITY-) safe
 and there are no plans to change this. Note that perl's builtin so-called
-theeads/ithreads are officially deprecated and should not be used.
+threads/ithreads are officially deprecated and should not be used.
 
 
 =head1 THE PERILS OF SETLOCALE
@@ -1723,6 +1771,32 @@
 afterwards.
 
 
+=head1 SOME HISTORY
+
+At the time this module was created there already were a number of JSON
+modules available on CPAN, so what was the reason to write yet another
+JSON module? While it seems there are many JSON modules, none of them
+correctly handled all corner cases, and in most cases their maintainers
+are unresponsive, gone missing, or not listening to bug reports for other
+reasons.
+
+Beginning with version 2.0 of the JSON module, when both JSON and
+JSON::XS are installed, then JSON will fall back on JSON::XS (this can be
+overridden) with no overhead due to emulation (by inheriting constructor
+and methods). If JSON::XS is not available, it will fall back to the
+compatible JSON::PP module as backend, so using JSON instead of JSON::XS
+gives you a portable JSON API that can be fast when you need it and
+doesn't require a C compiler when that is a problem.
+
+Somewhere around version 3, this module was forked into
+C<Cpanel::JSON::XS>, because its maintainer had serious trouble
+understanding JSON and insisted on a fork with many bugs "fixed" that
+weren't actually bugs, while spreading FUD about this module without
+actually giving any details on his accusations. You be the judge, but
+in my personal opinion, if you want quality, you will stay away from
+dangerous forks like that.
+
+
 =head1 BUGS
 
 While the goal of this module is to be correct, that unfortunately does
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/JSON-XS-3.04/XS.xs new/JSON-XS-4.0/XS.xs
--- old/JSON-XS-3.04/XS.xs      2017-08-17 03:54:33.000000000 +0200
+++ new/JSON-XS-4.0/XS.xs       2018-11-15 23:20:25.000000000 +0100
@@ -52,7 +52,7 @@
 
 #define F_PRETTY    F_INDENT | F_SPACE_BEFORE | F_SPACE_AFTER
 
-#define INIT_SIZE   32 // initial scalar size to be allocated
+#define INIT_SIZE   64 // initial scalar size to be allocated
 #define INDENT_STEP 3  // spaces per indentation level
 
 #define SHORT_STRING_LEN 16384 // special-case strings of up to this size
@@ -80,23 +80,26 @@
 #define ERR_NESTING_EXCEEDED "json text or perl structure exceeds maximum 
nesting level (max_depth set too low?)"
 
 #ifdef USE_ITHREADS
-# define JSON_SLOW 1
-# define JSON_STASH (json_stash ? json_stash : gv_stashpv ("JSON::XS", 1))
-# define BOOL_STASH (bool_stash ? bool_stash : gv_stashpv 
("Types::Serialiser::Boolean", 1))
+# define JSON_STASH (expect_true (json_stash) ? json_stash : gv_stashpv 
("JSON::XS", 1))
+# define BOOL_STASH (expect_true (bool_stash) ? bool_stash : gv_stashpv 
("Types::Serialiser::Boolean", 1))
+# define GET_BOOL(value) (expect_true (bool_ ## value) ? bool_ ## value : 
get_bool ("Types::Serialiser::" # value))
 #else
-# define JSON_SLOW 0
 # define JSON_STASH json_stash
 # define BOOL_STASH bool_stash
+# define GET_BOOL(value) bool_ ## value
 #endif
 
 // the amount of HEs to allocate on the stack, when sorting keys
 #define STACK_HES 64
 
 static HV *json_stash, *bool_stash; // JSON::XS::, Types::Serialiser::Boolean::
-static SV *bool_true, *bool_false, *sv_json;
+static SV *bool_false, *bool_true;
+static SV *sv_json;
 
 enum {
   INCR_M_WS = 0, // initial whitespace skipping, must be 0
+  INCR_M_TFN,    // inside true/false/null
+  INCR_M_NUM,    // inside number
   INCR_M_STR,    // inside string
   INCR_M_BS,     // inside backslash
   INCR_M_C0,     // inside comment in initial whitespace sequence
@@ -119,13 +122,16 @@
   STRLEN incr_pos; // the current offset into the text
   int incr_nest;   // {[]}-nesting level
   unsigned char incr_mode;
+
+  SV *v_false, *v_true;
 } JSON;
 
 INLINE void
 json_init (JSON *json)
 {
-  Zero (json, 1, JSON);
-  json->max_depth = 512;
+  static const JSON init = { F_ALLOW_NONREF, 512 };
+
+  *json = init;
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -182,7 +188,7 @@
   return SvGROW (sv, len1);
 }
 
-// decode an utf-8 character and return it, or (UV)-1 in
+// decode a utf-8 character and return it, or (UV)-1 in
 // case of an error.
 // we special-case "safe" characters from U+80 .. U+7FF,
 // but use the very good perl function to parse anything else.
@@ -778,10 +784,8 @@
 
       if (stash == bool_stash)
         {
-          if (SvIV (sv))
-            encode_str (enc, "true", 4, 0);
-          else
-            encode_str (enc, "false", 5, 0);
+          if (SvIV (sv)) encode_str (enc, "true" , 4, 0);
+          else           encode_str (enc, "false", 5, 0);
         }
       else if ((enc->json.flags & F_ALLOW_TAGS) && (method = 
gv_fetchmethod_autoload (stash, "FREEZE", 0)))
         {
@@ -789,7 +793,6 @@
           dSP;
 
           ENTER; SAVETMPS;
-          SAVESTACK_POS ();
           PUSHMARK (SP);
           EXTEND (SP, 2);
           // we re-bless the reference to get overload and other niceties right
@@ -811,12 +814,18 @@
           encode_ch (enc, ')');
           encode_ch (enc, '[');
 
-          while (count)
+          if (count)
             {
-              encode_sv (enc, SP[1 - count--]);
+              int i;
 
-              if (count)
-                encode_ch (enc, ',');
+              for (i = 0; i < count - 1; ++i)
+                {
+                  encode_sv (enc, SP[i + 1 - count]);
+                  encode_ch (enc, ',');
+                }
+
+              encode_sv (enc, TOPs);
+              SP -= count;
             }
 
           encode_ch (enc, ']');
@@ -1517,7 +1526,6 @@
               int count;
 
               ENTER; SAVETMPS;
-              SAVESTACK_POS ();
               PUSHMARK (SP);
               XPUSHs (HeVAL (he));
               sv_2mortal (sv);
@@ -1530,6 +1538,8 @@
                   FREETMPS; LEAVE;
                   return sv;
                 }
+              else if (count)
+                croak ("filter_json_single_key_object callbacks must not 
return more than one scalar");
 
               SvREFCNT_inc (sv);
               FREETMPS; LEAVE;
@@ -1542,7 +1552,6 @@
           int count;
 
           ENTER; SAVETMPS;
-          SAVESTACK_POS ();
           PUSHMARK (SP);
           XPUSHs (sv_2mortal (sv));
 
@@ -1554,6 +1563,8 @@
               FREETMPS; LEAVE;
               return sv;
             }
+          else if (count)
+            croak ("filter_json_object callbacks must not return more than one 
scalar");
 
           SvREFCNT_inc (sv);
           FREETMPS; LEAVE;
@@ -1668,31 +1679,33 @@
       case '5': case '6': case '7': case '8': case '9':
         return decode_num (dec);
 
-      case 't':
-        if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "true", 4))
+      case 'f':
+        if (dec->end - dec->cur >= 5 && !memcmp (dec->cur, "false", 5))
           {
-            dec->cur += 4;
-#if JSON_SLOW
-            bool_true = get_bool ("Types::Serialiser::true");
-#endif
-            return newSVsv (bool_true);
+            dec->cur += 5;
+
+            if (expect_false (!dec->json.v_false))
+              dec->json.v_false = GET_BOOL (false);
+
+            return newSVsv (dec->json.v_false);
           }
         else
-          ERR ("'true' expected");
+          ERR ("'false' expected");
 
         break;
 
-      case 'f':
-        if (dec->end - dec->cur >= 5 && !memcmp (dec->cur, "false", 5))
+      case 't':
+        if (dec->end - dec->cur >= 4 && !memcmp (dec->cur, "true", 4))
           {
-            dec->cur += 5;
-#if JSON_SLOW
-            bool_false = get_bool ("Types::Serialiser::false");
-#endif
-            return newSVsv (bool_false);
+            dec->cur += 4;
+
+            if (expect_false (!dec->json.v_true))
+              dec->json.v_true = GET_BOOL (true);
+
+            return newSVsv (dec->json.v_true);
           }
         else
-          ERR ("'false' expected");
+          ERR ("'true' expected");
 
         break;
 
@@ -1786,7 +1799,7 @@
       // check for trailing garbage
       decode_ws (&dec);
 
-      if (*dec.cur)
+      if (dec.cur != dec.end)
         {
           dec.err = "garbage after JSON object";
           SvREFCNT_dec (sv);
@@ -1834,9 +1847,17 @@
 
   for (;;)
     {
-      //printf ("loop pod %d *p<%c><%s>, mode %d nest %d\n", p - SvPVX 
(self->incr_text), *p, p, self->incr_mode, self->incr_nest);//D
       switch (self->incr_mode)
         {
+          // reached end of a scalar, see if we are inside a nested structure 
or not
+          end_of_scalar:
+            self->incr_mode = INCR_M_JSON;
+
+            if (self->incr_nest) // end of a scalar inside array, object or tag
+              goto incr_m_json;
+            else // end of scalar outside structure, json text ends here
+              goto interrupt;
+
           // only used for initial whitespace skipping
           case INCR_M_WS:
             for (;;)
@@ -1888,6 +1909,40 @@
 
             break;
 
+          // inside true/false/null
+          case INCR_M_TFN:
+          incr_m_tfn:
+            for (;;)
+              switch (*p++)
+                {
+                  case 'r': case 'u': case 'e': // tRUE, falsE, nUll
+                  case 'a': case 'l': case 's': // fALSe, nuLL
+                    // allowed
+                    break;
+                   
+                  default:
+                    --p;
+                    goto end_of_scalar;
+                }
+
+          // inside a number
+          case INCR_M_NUM:
+          incr_m_num:
+            for (;;)
+              switch (*p++)
+                {
+                  case 'e': case 'E': case '.': case '+':
+                  case '-':
+                  case '0': case '1': case '2': case '3': case '4':
+                  case '5': case '6': case '7': case '8': case '9':
+                    // allowed
+                    break;
+
+                  default:
+                    --p;
+                    goto end_of_scalar;
+                }
+
           // inside a string
           case INCR_M_STR:
           incr_m_str:
@@ -1896,12 +1951,7 @@
                 if (*p == '"')
                   {
                     ++p;
-                    self->incr_mode = INCR_M_JSON;
-
-                    if (!self->incr_nest)
-                      goto interrupt;
-
-                    goto incr_m_json;
+                    goto end_of_scalar;
                   }
                 else if (*p == '\\')
                   {
@@ -1941,6 +1991,21 @@
                         }
                       break;
 
+                    // the following three blocks handle scalars. this makes 
the parser
+                    // more strict than required inside arrays or objects, and 
could
+                    // be moved to a special case on the toplevel (except 
strings)
+                    case 't':
+                    case 'f':
+                    case 'n':
+                      self->incr_mode = INCR_M_TFN;
+                      goto incr_m_tfn;
+
+                    case '-':
+                    case '0': case '1': case '2': case '3': case '4':
+                    case '5': case '6': case '7': case '8': case '9':
+                      self->incr_mode = INCR_M_NUM;
+                      goto incr_m_num;
+
                     case '"':
                       self->incr_mode = INCR_M_STR;
                       goto incr_m_str;
@@ -1997,8 +2062,8 @@
 
        json_stash = gv_stashpv ("JSON::XS"                  , 1);
        bool_stash = gv_stashpv ("Types::Serialiser::Boolean", 1);
-        bool_true  = get_bool ("Types::Serialiser::true");
         bool_false = get_bool ("Types::Serialiser::false");
+        bool_true  = get_bool ("Types::Serialiser::true");
 
         sv_json = newSVpv ("JSON", 0);
         SvREADONLY_on (sv_json);
@@ -2010,8 +2075,13 @@
 
 void CLONE (...)
        CODE:
+        // as long as these writes are atomic, the race should not matter
+        // as existing threads either already use 0, or use the old value,
+        // which is sitll correct for the initial thread.
         json_stash = 0;
         bool_stash = 0;
+        bool_false = 0;
+        bool_true  = 0;
 
 void new (char *klass)
        PPCODE:
@@ -2025,6 +2095,21 @@
         )));
 }
 
+void boolean_values (JSON *self, SV *v_false = 0, SV *v_true = 0)
+       PPCODE:
+       self->v_false = newSVsv (v_false);
+       self->v_true  = newSVsv (v_true);
+        XPUSHs (ST (0));
+
+void get_boolean_values (JSON *self)
+       PPCODE:
+        if (self->v_false && self->v_true)
+         {
+            EXTEND (SP, 2);
+            PUSHs (self->v_false);
+            PUSHs (self->v_true);
+          }
+
 void ascii (JSON *self, int enable = 1)
        ALIAS:
         ascii           = F_ASCII
@@ -2270,6 +2355,8 @@
 
 void DESTROY (JSON *self)
        CODE:
+        SvREFCNT_dec (self->v_false);
+        SvREFCNT_dec (self->v_true);
         SvREFCNT_dec (self->cb_sk_object);
         SvREFCNT_dec (self->cb_object);
         SvREFCNT_dec (self->incr_text);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/JSON-XS-3.04/bin/json_xs new/JSON-XS-4.0/bin/json_xs
--- old/JSON-XS-3.04/bin/json_xs        2017-07-07 04:31:43.000000000 +0200
+++ new/JSON-XS-4.0/bin/json_xs 2018-11-15 21:48:29.000000000 +0100
@@ -193,7 +193,7 @@
    "string"        => sub { $_ },
    "json"          => sub { encode_json $_ },
    "json-utf-8"    => sub { encode_json $_ },
-   "json-pretty"   => sub { JSON::XS->new->utf8->pretty->encode ($_) },
+   "json-pretty"   => sub { JSON::XS->new->utf8->pretty->canonical->encode 
($_) },
    "json-utf-16le" => sub { encode "utf-16le", JSON::XS->new->encode ($_) },
    "json-utf-16be" => sub { encode "utf-16be", JSON::XS->new->encode ($_) },
    "json-utf-32le" => sub { encode "utf-32le", JSON::XS->new->encode ($_) },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/JSON-XS-3.04/t/02_error.t 
new/JSON-XS-4.0/t/02_error.t
--- old/JSON-XS-3.04/t/02_error.t       2008-11-20 04:59:53.000000000 +0100
+++ new/JSON-XS-4.0/t/02_error.t        2018-11-15 21:22:22.000000000 +0100
@@ -1,4 +1,4 @@
-BEGIN { $| = 1; print "1..31\n"; }
+BEGIN { $| = 1; print "1..35\n"; }
 
 use utf8;
 use JSON::XS;
@@ -20,7 +20,7 @@
 eval { JSON::XS->new->allow_nonref->decode ('"\ud800"') }; ok $@ =~ /missing 
low /;
 eval { JSON::XS->new->allow_nonref (1)->decode ('"\ud800\u1234"') }; ok $@ =~ 
/surrogate pair /;
 
-eval { JSON::XS->new->decode ('null') }; ok $@ =~ /allow_nonref/;
+eval { JSON::XS->new->allow_nonref (0)->decode ('null') }; ok $@ =~ 
/allow_nonref/;
 eval { JSON::XS->new->allow_nonref (1)->decode ('+0') }; ok $@ =~ /malformed/;
 eval { JSON::XS->new->allow_nonref->decode ('.2') }; ok $@ =~ /malformed/;
 eval { JSON::XS->new->allow_nonref (1)->decode ('bare') }; ok $@ =~ 
/malformed/;
@@ -44,4 +44,8 @@
 
 eval { decode_json ("\"\xa0") }; ok $@ =~ /malformed.*character/;
 eval { decode_json ("\"\xa0\"") }; ok $@ =~ /malformed.*character/;
+eval { decode_json ("1\x01") }; ok $@ =~ /garbage after/;
+eval { decode_json ("1\x00") }; ok $@ =~ /garbage after/;
+eval { decode_json ("\"\"\x00") }; ok $@ =~ /garbage after/;
+eval { decode_json ("[]\x00") }; ok $@ =~ /garbage after/;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/JSON-XS-3.04/t/18_json_checker.t 
new/JSON-XS-4.0/t/18_json_checker.t
--- old/JSON-XS-3.04/t/18_json_checker.t        2007-10-10 19:38:47.000000000 
+0200
+++ new/JSON-XS-4.0/t/18_json_checker.t 2018-11-15 21:19:06.000000000 +0100
@@ -6,7 +6,7 @@
 use strict;
 no warnings;
 use Test::More;
-BEGIN { plan tests => 39 };
+BEGIN { plan tests => 38 };
 
 use JSON::XS;
 
@@ -31,8 +31,6 @@
 }
 
 __DATA__
-"A JSON payload should be an object or array, not a string."
-# fail1.json
 {"Extra value after close": true} "misplaced quoted value"
 # fail10.json
 {"Illegal expression": 1 + 2}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/JSON-XS-3.04/t/19_incr.t new/JSON-XS-4.0/t/19_incr.t
--- old/JSON-XS-3.04/t/19_incr.t        2013-05-23 11:20:06.000000000 +0200
+++ new/JSON-XS-4.0/t/19_incr.t 2018-11-15 23:00:55.000000000 +0100
@@ -3,7 +3,7 @@
 use strict;
 no warnings;
 use Test::More;
-BEGIN { plan tests => 697 };
+BEGIN { plan tests => 745 };
 
 use JSON::XS;
 
@@ -21,16 +21,23 @@
       $coder->incr_parse ($b);
 
       my $data = $coder->incr_parse;
-      ok ($data);
-      ok ($coder->encode ($data) eq $coder->encode ($coder->decode ($text)), 
"data");
+      #ok (defined $data, "split<$a><$b>");
+      ok (defined $data, "split");
+      my $e1 = $coder->encode ($data);
+      my $e2 = $coder->encode ($coder->decode ($text));
+      #ok ($e1 eq $e2, "data<$a><$b><$e1><$e2>");
+      #ok ($coder->incr_text =~ /^\s*$/, "tailws<$a><$b>");
+      ok ($e1 eq $e2, "data");
       ok ($coder->incr_text =~ /^\s*$/, "tailws");
    }
 }
 
-splitter +JSON::XS->new              , '  ["x\\"","\\u1000\\\\n\\nx",1,{"\\\\" 
:5 , "": "x"}]';
-splitter +JSON::XS->new              , '[ "x\\"","\\u1000\\\\n\\nx" , 1,{"\\\\ 
" :5 , "": " x"} ] ';
-splitter +JSON::XS->new->allow_nonref, '"test"';
-splitter +JSON::XS->new->allow_nonref, ' "5" ';
+splitter +JSON::XS->new->allow_nonref (0), '  
["x\\"","\\u1000\\\\n\\nx",1,{"\\\\" :5 , "": "x"}]';
+splitter +JSON::XS->new->allow_nonref (0), '[ "x\\"","\\u1000\\\\n\\nx" , 
1,{"\\\\ " :5 , "": " x"} ] ';
+splitter +JSON::XS->new                  , '"test"';
+splitter +JSON::XS->new                  , ' "5" ';
+splitter +JSON::XS->new                  , '-1e5';
+splitter +JSON::XS->new                  , ' 0.00E+00 ';
 
 {
    my $text = '[5],{"":1} , [ 1,2, 3], {"3":null}';


Reply via email to