Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package perl-Cpanel-JSON-XS for 
openSUSE:Factory checked in at 2022-05-12 23:00:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Cpanel-JSON-XS (Old)
 and      /work/SRC/openSUSE:Factory/.perl-Cpanel-JSON-XS.new.1538 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-Cpanel-JSON-XS"

Thu May 12 23:00:22 2022 rev:33 rq:976454 version:4.28

Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-Cpanel-JSON-XS/perl-Cpanel-JSON-XS.changes  
2021-10-23 00:52:14.449154847 +0200
+++ 
/work/SRC/openSUSE:Factory/.perl-Cpanel-JSON-XS.new.1538/perl-Cpanel-JSON-XS.changes
        2022-05-12 23:00:46.944830802 +0200
@@ -1,0 +2,16 @@
+Fri May  6 03:06:18 UTC 2022 - Tina M??ller <timueller+p...@suse.de>
+
+- updated to 4.28
+   see /usr/share/doc/packages/perl-Cpanel-JSON-XS/Changes
+
+  4.28 2022-05-05 (rurban)
+          - Validate the JSON struct which might get corrupted by wrong 
FREEZE/THAW
+            methods, or other serializers, or corrupting our magic object. (GH 
#192)
+          - Improve our DESTROY and END methods to avoid NULL dereferences.
+            Fixes perl-compiler/#438
+          - Fix 3 tests in t/20_unknown.t with the latest 5.35.10 bool 
enhancements
+            and JSON::PP (GH #194)
+          - Fix t/118_type.t with Windows ivtype long long. (GH #178)
+          - Added github actions
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ perl-Cpanel-JSON-XS.spec ++++++
--- /var/tmp/diff_new_pack.Bnzl0A/_old  2022-05-12 23:00:47.396831409 +0200
+++ /var/tmp/diff_new_pack.Bnzl0A/_new  2022-05-12 23:00:47.400831415 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package perl-Cpanel-JSON-XS
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,10 +18,10 @@
 
 %define cpan_name Cpanel-JSON-XS
 Name:           perl-Cpanel-JSON-XS
-Version:        4.27
+Version:        4.28
 Release:        0
-Summary:        CPanel fork of JSON::XS, fast and correct serializing
 License:        Artistic-1.0 OR GPL-1.0-or-later
+Summary:        CPanel fork of JSON::XS, fast and correct serializing
 URL:            https://metacpan.org/release/%{cpan_name}
 Source0:        
https://cpan.metacpan.org/authors/id/R/RU/RURBAN/%{cpan_name}-%{version}.tar.gz
 Source1:        cpanspec.yml

++++++ Cpanel-JSON-XS-4.27.tar.gz -> Cpanel-JSON-XS-4.28.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.27/.github/workflows/testsuite.yml 
new/Cpanel-JSON-XS-4.28/.github/workflows/testsuite.yml
--- old/Cpanel-JSON-XS-4.27/.github/workflows/testsuite.yml     1970-01-01 
01:00:00.000000000 +0100
+++ new/Cpanel-JSON-XS-4.28/.github/workflows/testsuite.yml     2022-05-05 
16:31:26.000000000 +0200
@@ -0,0 +1,143 @@
+name: testsuite
+
+on:
+  push:
+    branches:
+      - "*"
+    tags-ignore:
+      - "*"
+  pull_request:
+
+jobs:
+  ubuntu:
+    env:
+      PERL_USE_UNSAFE_INC: 0
+      AUTHOR_TESTING: 1
+      AUTOMATED_TESTING: 1
+      RELEASE_TESTING: 1
+
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v1
+      - run: perl -V
+      - name: install cpan deps
+        uses: perl-actions/install-with-cpm@v1.3
+        with:
+          install: |
+            Data::Dumper
+            Devel::Peek
+            Mojo::JSON
+            JSON::XS
+            JSON
+            Test::LeakTrace
+            Test::MinimumVersion
+            Perl::MinimumVersion
+            Test::CPAN::Meta
+            Test::Pod
+            Test::Pod::Coverage
+            Test::Spelling
+            Pod::Spell::CommonMistakes
+            Test::CPAN::Changes
+            Test::CheckChanges
+            Class::XSAccessor
+            Text::CSV_XS
+            List::MoreUtils
+            Test::Kwalitee
+      - run: perl Makefile.PL
+      - run: make test
+
+  linux:
+    name: "perl ${{ matrix.perl-version }}"
+    needs: [ubuntu]
+    env:
+      PERL_USE_UNSAFE_INC: 0
+      AUTOMATED_TESTING: 1
+      AUTHOR_TESTING: 0
+      RELEASE_TESTING: 0
+
+    runs-on: ubuntu-latest
+
+    strategy:
+      fail-fast: false
+      matrix:
+        perl-version:
+          [
+            "5.34",
+            "5.32",
+            "5.30",
+            "5.28",
+            "5.26",
+            "5.24",
+            "5.22",
+            "5.20",
+            "5.18",
+            "5.16",
+            "5.14",
+            "5.12",
+            "5.10",
+            "5.8",
+          ]
+
+    steps:
+      - uses: actions/checkout@v1
+      - uses: shogo82148/actions-setup-perl@v1
+        with:
+          perl-version: ${{ matrix.perl-version }}
+      - run: perl -V
+      - name: install cpan deps
+        uses: perl-actions/install-with-cpm@v1.3
+        with:
+          sudo: false
+          install: |
+            Data::Dumper
+            Devel::Peek
+            JSON::XS
+            JSON
+      - run: perl Makefile.PL
+      - run: make test
+
+  macOS:
+    needs: [ubuntu]
+    env:
+      PERL_USE_UNSAFE_INC: 0
+      AUTOMATED_TESTING: 1
+      AUTHOR_TESTING: 0
+      RELEASE_TESTING: 0
+
+    runs-on: macOS-latest
+
+    strategy:
+      fail-fast: false
+      matrix:
+        perl-version: [latest]
+
+    steps:
+      - uses: actions/checkout@v1
+      - run: perl -V
+      - run: perl Makefile.PL
+      - run: make test
+
+  windows:
+    needs: [ubuntu]
+    env:
+      PERL_USE_UNSAFE_INC: 0
+      AUTOMATED_TESTING: 1
+      AUTHOR_TESTING: 0
+      RELEASE_TESTING: 0
+      VCPKG_DEFAULT_TRIPLET: x64-windows
+
+    runs-on: windows-latest
+
+    strategy:
+      fail-fast: false
+      matrix:
+        perl-version: [latest]
+
+    steps:
+      - uses: actions/checkout@master
+      - run: perl -V
+      - run: perl Makefile.PL
+      #- run: prove -vb t/*.t
+      - run: make test
+        continue-on-error: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.27/Changes 
new/Cpanel-JSON-XS-4.28/Changes
--- old/Cpanel-JSON-XS-4.27/Changes     2021-10-14 21:15:41.000000000 +0200
+++ new/Cpanel-JSON-XS-4.28/Changes     2022-05-05 16:44:35.000000000 +0200
@@ -2,6 +2,16 @@
 
 TODO: http://stevehanov.ca/blog/index.php?id=104 compression
 
+4.28 2022-05-05 (rurban)
+        - Validate the JSON struct which might get corrupted by wrong 
FREEZE/THAW
+          methods, or other serializers, or corrupting our magic object. (GH 
#192)
+        - Improve our DESTROY and END methods to avoid NULL dereferences.
+          Fixes perl-compiler/#438
+        - Fix 3 tests in t/20_unknown.t with the latest 5.35.10 bool 
enhancements
+          and JSON::PP (GH #194)
+        - Fix t/118_type.t with Windows ivtype long long. (GH #178)
+        - Added github actions
+
 4.27 2021-10-13 (rurban)
         - Only add -Werror=declaration-after-statement for 5.035004 and 
earlier (PR #186 nwc)
        - Fix 125_shared_boolean.t for threads (PR #184 Sinan Unur)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.27/MANIFEST 
new/Cpanel-JSON-XS-4.28/MANIFEST
--- old/Cpanel-JSON-XS-4.27/MANIFEST    2021-10-14 21:17:11.000000000 +0200
+++ new/Cpanel-JSON-XS-4.28/MANIFEST    2022-05-05 16:45:13.000000000 +0200
@@ -1,5 +1,6 @@
 .appveyor.yml
 .github/FUNDING.yml
+.github/workflows/testsuite.yml
 .travis.yml
 .whitesource
 COPYING
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.27/META.json 
new/Cpanel-JSON-XS-4.28/META.json
--- old/Cpanel-JSON-XS-4.27/META.json   2021-10-14 21:17:11.000000000 +0200
+++ new/Cpanel-JSON-XS-4.28/META.json   2022-05-05 16:45:13.000000000 +0200
@@ -4,7 +4,7 @@
       "Reini Urban <rur...@cpan.org>"
    ],
    "dynamic_config" : 0,
-   "generated_by" : "ExtUtils::MakeMaker version 7.38, CPAN::Meta::Converter 
version 2.150010",
+   "generated_by" : "ExtUtils::MakeMaker version 7.64, CPAN::Meta::Converter 
version 2.150010",
    "license" : [
       "perl_5"
    ],
@@ -100,7 +100,7 @@
          "url" : "https://github.com/rurban/Cpanel-JSON-XS";
       }
    },
-   "version" : "4.27",
+   "version" : "4.28",
    "x_contributors" : [
       "Ashley Willis <ashl...@cpan.org>",
       "Chip Salzenberg <c...@pobox.com>",
@@ -127,5 +127,5 @@
       "Syohei Yoshida <syo...@gmail.com>",
       "tevfik1903 <tevfik1...@users.noreply.github.com>"
    ],
-   "x_serialization_backend" : "JSON::PP version 2.97001"
+   "x_serialization_backend" : "JSON::PP version 4.06"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.27/META.yml 
new/Cpanel-JSON-XS-4.28/META.yml
--- old/Cpanel-JSON-XS-4.27/META.yml    2021-10-14 21:17:10.000000000 +0200
+++ new/Cpanel-JSON-XS-4.28/META.yml    2022-05-05 16:45:13.000000000 +0200
@@ -22,7 +22,7 @@
   Config: '0'
   ExtUtils::MakeMaker: '0'
 dynamic_config: 0
-generated_by: 'ExtUtils::MakeMaker version 7.38, CPAN::Meta::Converter version 
2.150010'
+generated_by: 'ExtUtils::MakeMaker version 7.64, CPAN::Meta::Converter version 
2.150010'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -48,7 +48,7 @@
   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.27'
+version: '4.28'
 x_contributors:
   - 'Ashley Willis <ashl...@cpan.org>'
   - 'Chip Salzenberg <c...@pobox.com>'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.27/README 
new/Cpanel-JSON-XS-4.28/README
--- old/Cpanel-JSON-XS-4.27/README      2021-10-14 21:17:13.000000000 +0200
+++ new/Cpanel-JSON-XS-4.28/README      2022-05-05 16:45:16.000000000 +0200
@@ -144,6 +144,9 @@
 
     - relaxed mode, allowing many popular extensions
 
+    - protect our magic object from corruption by wrong or missing external
+    methods, like FREEZE/THAW or serialization with other methods.
+
     - additional fixes for:
 
       - [cpan #88061] AIX atof without USE_LONG_DOUBLE
@@ -180,9 +183,9 @@
 
     - support many more options and methods from JSON::PP: stringify_infnan,
     allow_unknown, allow_stringify, allow_barekey, encode_stringify,
-    allow_bignum, allow_singlequote, sort_by (partially), escape_slash,
-    convert_blessed, ... optional decode_json(, allow_nonref) arg. relaxed
-    implements allow_dupkeys.
+    allow_bignum, allow_singlequote, dupkeys_as_arrayref, sort_by
+    (partially), escape_slash, convert_blessed, ... optional decode_json(,
+    allow_nonref) arg. relaxed implements allow_dupkeys.
 
     - support all 5 unicode BOM's: UTF-8, UTF-16LE, UTF-16BE, UTF-32LE,
     UTF-32BE, encoding internally to UTF-8.
@@ -760,6 +763,25 @@
         See <http://seriot.ch/parsing_json.php#24>: RFC 7159 section 4: "The
         names within an object should be unique."
 
+    $json = $json->dupkeys_as_arrayref ([$enable])
+    $enabled = $json->get_dupkeys_as_arrayref
+        If enabled, allow decoding of duplicate keys in hashes and store the
+        values as arrayref in the hash instead. By default duplicate keys
+        are forbidden. Enabling this also enables the "allow_dupkeys"
+        option, but disabling this does not disable the "allow_dupkeys"
+        option.
+
+        Example:
+
+            $json->dupkeys_as_arrayref;
+            print encode_json ($json->decode ('{"a":"b","a":"c"}'));
+
+              => {"a":["b","c"]}
+
+        This changes the result structure, thus cannot be enabled by
+        default. The client must be aware of it. The resulting arrayref is
+        not yet marked somehow (blessed or such).
+
     $json = $json->allow_blessed ([$enable])
     $enabled = $json->get_allow_blessed
         If $enable is true (or missing), then the "encode" method will not
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.27/SIGNATURE 
new/Cpanel-JSON-XS-4.28/SIGNATURE
--- old/Cpanel-JSON-XS-4.27/SIGNATURE   2021-10-14 21:17:13.000000000 +0200
+++ new/Cpanel-JSON-XS-4.28/SIGNATURE   2022-05-05 16:45:15.000000000 +0200
@@ -16,17 +16,18 @@
 
 SHA256 aac2b4bbaa7b93eaf72300f60e167a17e05adcd721087f735ba55d2900f31490 
.appveyor.yml
 SHA256 082201a3cbd62a55f2e58ffbb991c4b2bb806de0009bc9497ffcc07202f60855 
.github/FUNDING.yml
+SHA256 5955b1ab56c8a65fc72542d07c24629e8ba75cf7900c706787fa81b8670ccbf6 
.github/workflows/testsuite.yml
 SHA256 a3c34aba52e269e6cec558ecf9cff393138574189fdff26b183bee9cc2e0434f 
.travis.yml
 SHA256 c3f2a1a4f66382f796f71a571946722edba53cf3238152b26fd325f4c2f1a20f 
.whitesource
 SHA256 8de3540a3cd7ecc9a9dcb48975fe852c082fe17d4462f87bb72aa7cc47f083ad COPYING
-SHA256 b1e171ef31c9946918545075029aab6b7b3bd8f84243ca0f33140a88f2199c11 Changes
-SHA256 9a862bfa951e3d5b43c2dcb95767dbf15ed2ee3af872442d3815795757533f29 
MANIFEST
-SHA256 20014d3e98df165912566f273aa9e89c27b77f85585be69b9369ce74fa88aecf 
META.json
-SHA256 cc40be0ced242f5f9124b8d4d2d8d61182a9e3ba886c10e6639a1e9fc08b6fef 
META.yml
+SHA256 c572eb1be9636dcb5985310d7f822a43ba97768cd3f77c686061b0ee1cd70350 Changes
+SHA256 a5378ebe65273d49047a21e94af087f70a303793ffed2a695c800ed965ac185d 
MANIFEST
+SHA256 7f50819e95246a09af86352d7da2ef39316a3d9b208f0de1765ad7bd6acea52e 
META.json
+SHA256 137ace3243380ed3d3a32b80fd24777f57a7ef27fb03edf247601f8c6f2b251d 
META.yml
 SHA256 31d74c68c91639bc34e18541091616d226713c6c49168d42eefab58535f5cd4a 
Makefile.PL
-SHA256 8f148ef8274dedead04152016f433003da991dbdfb1b12dac84674b4845e2d8e README
-SHA256 5c2ba9294ae2d6a72d0b948379bddbcbbb24d6d4e0d6ac7e7374fe3637849c25 XS.pm
-SHA256 44d4fe9c1f9f186a65829357c2346a8c00c0f33ae5c8ab9f411d5d827bf7e0d7 XS.xs
+SHA256 77d93364f2517135118fa729c598ac64a02ec7d8901fa69b8327a65596f72a86 README
+SHA256 5ab5ab62416fbadf4394f8ce466e4bb380c12e5f55fd6ed7a0ffca9a710d072a XS.pm
+SHA256 1c4055f100c6607ffdaf3e53a2c395c7232d6941bfd1691a835cdfd069453955 XS.xs
 SHA256 c95e4b970183cbd6d1ec9c88c37a80f12bd2b66ed6be3c008ffd578d2f622c01 
XS/Boolean.pm
 SHA256 20596259e7e399ed1984a469a9a907be878499406d5285a11f1ab98f93aff44f 
XS/Type.pm
 SHA256 2f34a530b7ce981b0df9aacd2b6944ccf74c4a7f8bb49fde57b342663e7feb26 
bin/cpanel_json_xs
@@ -57,7 +58,7 @@
 SHA256 d8fc2223d440343e68c2c4bb0a62b191c468f9c42b4ef0a361219baf9449b36a 
t/115_tie_ixhash.t
 SHA256 5a7c6c338b74f6f272510723f0605d09c16deba3922e2b29cb4b057d5d6b2bc4 
t/116_incr_parse_fixed.t
 SHA256 08ad2b745ea647529d043e1932c560d70a2655de8749ea473288a747d86284e6 
t/117_numbers.t
-SHA256 2707ce86407dec731fd0819c0653218232a37bdec3f9ff401d94fefdfcadc593 
t/118_type.t
+SHA256 34a7fd54a9c17af5bc643bf237d334b9f664c4af9fc699e8af2d6347696ef13e 
t/118_type.t
 SHA256 5f4f0f1d4221f5b5c28c1988f4d127462a42f36ae82fedd7319c8e0fbfbd57eb 
t/119_type_decode.t
 SHA256 8f0f898f0499424740eea5e2537e97faee949b1e3981a1588b1a61645d942d3c 
t/11_pc_expo.t
 SHA256 67295534f9f44b6c2fd9375a4baff3b959318ce2468d466204efd1aeb8caadae 
t/120_type_all_string.t
@@ -72,13 +73,13 @@
 SHA256 1585a6aecec5c73b7a6f70982b3bcc1edc1d63ca55467223ab0d6f0956254bc4 
t/18_json_checker.t
 SHA256 9f9006c1f925d9ace7d1621e1479c21f9b50459ab57aa0046209fed2b3e66530 
t/19_incr.t
 SHA256 dde73ed3cfc0e28d064f61fc08871accf88b780aee06a3cb0040f59f04c1ff36 
t/20_faihu.t
-SHA256 0028cd6f4b5c98721533a12eed58d0701483fb7639e719427c03fa5cd48a46ee 
t/20_unknown.t
+SHA256 e2a3ec29b5c30ab934f54864aab62dcfbaa54d8865829bd6fed5f07cbe4d9d58 
t/20_unknown.t
 SHA256 388f8e0f0e41c9921aedc67313f8b89bdd08b95ced0dba242986d3b76d9a1688 
t/21_evans.t
 SHA256 3da823eab55abb6dca05e8bc6111d3b59ea18c4ee270baf6413d9a45042ff48c 
t/22_comment_at_eof.t
 SHA256 2a6506fb07b27b1fef52b251d3876d23bd572596ff487d37c2f6597be554836c 
t/23_array_ctx.t
 SHA256 a8dfccba0b60b0fc91812fcfd96656e993abb74970509926d738c67a58641f01 
t/24_freeze_recursion.t
 SHA256 3d81e94b5d3407ba3df47ccace0aaf8f16bad9da3016e74f653e150629ce5b36 
t/25_boolean.t
-SHA256 25d388275acde51b3d768b80c7a4b03d47988cc3919c81aa71b657250b5d4099 
t/26_duplicate.t
+SHA256 e7297f97fe3fea65c865658675b72e667b37b201e7fec8b8128f2006f8999d86 
t/26_duplicate.t
 SHA256 03a2061b4742ea591961a4ce7403feac91998c0909dbde982c465ce3d2c39706 
t/30_jsonspec.t
 SHA256 cf2181a691d5e1862d71e4e902928a0d899b9671e3633584efa8ae3f5cc0d174 
t/31_bom.t
 SHA256 59c743137453c8c4e9e785a15dcd057b0209d5ce160d683d7ab416dc37a92b6d 
t/52_object.t
@@ -445,12 +446,12 @@
 SHA256 aca6f846869ab2e4881e807739086e1535b1438bd0e23d7a021360742736a6a9 
xt/pod.t
 -----BEGIN PGP SIGNATURE-----
 
-iQEzBAEBAwAdFiEEKJWogdNCcPq/6PdHtPYzOeZdZBQFAmFogjgACgkQtPYzOeZd
-ZBRm0Qf+MlDXjdzOC/2IctdnGkrLJDiT3HP1+1FZvN6+eOQFXUDubg+kK5rn372O
-etYQfubhCUywfzCPFVJjdeGB8gMEIROSiGN/gPgIM1lJ9E5zw10j/7PJmqsu+Kwv
-m4USDEzgLV4bxq17IlgoSAeV0mgthGEIOpASfUHjOvEJHcJsq6QucLBKonwNlm0L
-WZ/WuPSYeh4QjvcPqUkQOnAIFPeq4PFADoePK2H0QBNelGhWQVn0vtZw5lP17hVg
-+ymy1gN6GiMsvRobSbHHCPDtr4kqWnYCkqgOUFy7VCkNXkSFA1RYxfVrNBRKOk/b
-Iubj6VYO8adTxyeHQ2FUDmJsUPUV6A==
-=0Xe1
+iQEzBAEBAwAdFiEEKJWogdNCcPq/6PdHtPYzOeZdZBQFAmJz4voACgkQtPYzOeZd
+ZBRNZgf/VFEreSdMRn5wzSNr4BurmZCEJNq5JBLzg16RNkBKnoGCeBr9zH8i4hXv
+nIvfywfwy2D+59LNMKa6vyGVsNf0s6eozcXOYK238qkUlDtNHISq766AukCikDkp
+jpfTCFL89cYqv1PQM9d4oHudMSXaon87LwaiOBKOMb81KfnnW4N6ZmZ0gjcLQPHU
+/ttPvGFRBbrPADe9U3mGyZ6YaUEePbM7PqyoGamf2ZOyrzxYbR1Kmf6ZNtCVuwUp
+cBGeHfH7EWXdXhGOJ2+JF1fq0BeTb5WgSXv/Wf9OaMospUPcAL1IyHIr7RW6PLv6
+bxzKVtYjk4RkNdanX+i7BhrGj+DKnw==
+=MtF3
 -----END PGP SIGNATURE-----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.27/XS.pm 
new/Cpanel-JSON-XS-4.28/XS.pm
--- old/Cpanel-JSON-XS-4.27/XS.pm       2021-10-14 21:15:41.000000000 +0200
+++ new/Cpanel-JSON-XS-4.28/XS.pm       2022-05-05 16:44:35.000000000 +0200
@@ -1,5 +1,5 @@
 package Cpanel::JSON::XS;
-our $VERSION = '4.27';
+our $VERSION = '4.28';
 our $XS_VERSION = $VERSION;
 # $VERSION = eval $VERSION;
 
@@ -157,6 +157,9 @@
 
 - relaxed mode, allowing many popular extensions
 
+- protect our magic object from corruption by wrong or missing external
+  methods, like FREEZE/THAW or serialization with other methods.
+
 - additional fixes for:
 
   - [cpan #88061] AIX atof without USE_LONG_DOUBLE
@@ -193,9 +196,9 @@
 
 - support many more options and methods from JSON::PP:
   stringify_infnan, allow_unknown, allow_stringify, allow_barekey,
-  encode_stringify, allow_bignum, allow_singlequote, sort_by
-  (partially), escape_slash, convert_blessed, ...  optional
-  decode_json(, allow_nonref) arg.
+  encode_stringify, allow_bignum, allow_singlequote, dupkeys_as_arrayref,
+  sort_by (partially), escape_slash, convert_blessed, ...
+  optional decode_json(, allow_nonref) arg.
   relaxed implements allow_dupkeys.
 
 - support all 5 unicode L<BOM|/BOM>'s: UTF-8, UTF-16LE, UTF-16BE, UTF-32LE,
@@ -661,11 +664,10 @@
 Allow decoding of duplicate keys in hashes. By default duplicate keys are 
forbidden.
 See L<http://seriot.ch/parsing_json.php#24>:
 RFC 7159 section 4: "The names within an object should be unique."
-See the L</allow_dupkeys> option.
+See the C<allow_dupkeys> option.
 
 =back
 
-
 =item $json = $json->canonical ([$enable])
 
 =item $enabled = $json->get_canonical
@@ -883,6 +885,26 @@
 See L<http://seriot.ch/parsing_json.php#24>:
 RFC 7159 section 4: "The names within an object should be unique."
 
+=item $json = $json->dupkeys_as_arrayref ([$enable])
+
+=item $enabled = $json->get_dupkeys_as_arrayref
+
+If enabled, allow decoding of duplicate keys in hashes and store the
+values as arrayref in the hash instead.  By default duplicate keys are
+forbidden.  Enabling this also enables the L</allow_dupkeys> option,
+but disabling this does not disable the L</allow_dupkeys> option.
+
+Example:
+
+    $json->dupkeys_as_arrayref;
+    print encode_json ($json->decode ('{"a":"b","a":"c"}'));
+
+      => {"a":["b","c"]}
+
+This changes the result structure, thus cannot be enabled by default.
+The client must be aware of it. The resulting arrayref is not yet marked 
somehow
+(blessed or such).
+
 =item $json = $json->allow_blessed ([$enable])
 
 =item $enabled = $json->get_allow_blessed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.27/XS.xs 
new/Cpanel-JSON-XS-4.28/XS.xs
--- old/Cpanel-JSON-XS-4.27/XS.xs       2021-04-10 09:55:16.000000000 +0200
+++ new/Cpanel-JSON-XS-4.28/XS.xs       2022-05-05 16:44:35.000000000 +0200
@@ -301,6 +301,9 @@
 # endif
 #endif
 
+// i.e. "JSON" in big-endian
+#define JSON_MAGIC 0x4A534F4E
+
 /* types */
 #define JSON_TYPE_SCALAR       0x0000
 #define JSON_TYPE_BOOL         0x0001
@@ -352,6 +355,8 @@
 #define F_ALLOW_DUPKEYS   0x00800000UL
 #define F_REQUIRE_TYPES   0x01000000UL
 #define F_TYPE_ALL_STRING 0x02000000UL
+#define F_DUPKEYS_AS_AREF 0x04000000UL
+#define F_DUPKEYS_FIRST   0x08000000UL /* internal only */
 #define F_HOOK            0x80000000UL /* some hooks exist, so slow-path 
processing */
 
 #define F_PRETTY    F_INDENT | F_SPACE_BEFORE | F_SPACE_AFTER
@@ -432,6 +437,9 @@
   int incr_nest;   /* {[]}-nesting level */
   unsigned char incr_mode;
   unsigned char infnan_mode;
+
+  /* corruption check */
+  U32 magic;
 } JSON;
 
 INLINE void
@@ -440,11 +448,11 @@
   Zero (json, 1, JSON);
   json->max_depth     = 512;
   json->indent_length = INDENT_STEP;
+  json->magic = JSON_MAGIC;
 }
 
-/* dTHX/threads TODO*/
-/* END dtor call not needed, all of these *s refcnts are owned by the stash
-  treem not C code */
+/* dTHX/threads TODO
+   END dtor not needed for these, all of these *s refcnts are owned by the 
stash. */
 static void
 init_MY_CXT(pTHX_ my_cxt_t * cxt)
 {
@@ -468,6 +476,15 @@
 /*/////////////////////////////////////////////////////////////////////////// 
*/
 /* utility functions */
 
+/* Validate the JSON struct which might get corrupted by wrong FREEZE/THAW
+   methods, or other serializers, or corrupting our magic object.
+   E.g. https://github.com/rurban/Cpanel-JSON-XS/issues/192 */
+INLINE bool
+json_validate (JSON *json)
+{
+    return json->magic == JSON_MAGIC;
+}
+
 /* Unpacks the 2 boolean objects from the global references */
 INLINE SV *
 get_bool (pTHX_ const char *name)
@@ -505,11 +522,11 @@
     }
 }
 
-/* decode an 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. */
-/* note that we never call this function for a ascii codepoints */
+/* Decode an 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.
+   note that we never call this function for a ascii codepoints. */
 INLINE UV
 decode_utf8 (pTHX_ unsigned char *s, STRLEN len, int relaxed, STRLEN *clen)
 {
@@ -727,11 +744,12 @@
         }
     }
 
-  /* This relies greatly on the quality of the pow () */
-  /* implementation of the platform, but a good */
-  /* implementation is hard to beat. */
-  /* (IEEE 754 conformant ones are required to be exact) */
-  if (postdp) *expo -= eaccum;
+    /* This relies greatly on the quality of the pow ()
+       implementation of the platform, but a good
+       implementation is hard to beat.
+       (IEEE 754 conformant ones are required to be exact) */
+    if (postdp)
+      *expo -= eaccum;
 #ifdef HAVE_NO_POWL
   /* powf() unfortunately is not accurate enough */
   *accum += uaccum * fs_powEx(10., *expo );
@@ -1737,6 +1755,9 @@
           items = count;
           SPAGAIN;
 
+          if (!json_validate (&enc->json))
+              croak (NULL);
+
           /* catch this surprisingly common error */
           if (SvROK (TOPs) && SvRV (TOPs) == sv)
             croak ("%s::FREEZE method returned same object as was passed 
instead of a new one",
@@ -1779,6 +1800,9 @@
           call_sv ((SV *)GvCV (method), G_SCALAR);
           SPAGAIN;
           
+          if (!json_validate (&enc->json))
+              croak (NULL);
+
           /* catch this surprisingly common error */
           if (SvROK (TOPs) && SvRV (TOPs) == sv)
             croak ("%s::TO_JSON method returned same object as was passed 
instead of a new one", HvNAME (SvSTASH (sv)));
@@ -2482,6 +2506,9 @@
               eval_sv (pv, G_SCALAR);
               SvREFCNT_dec (pv);
 
+              if (!json_validate (&enc->json))
+                  croak (NULL);
+              
               /* rethrow current error */
               errsv = ERRSV;
               if (SvROK (errsv))
@@ -3792,6 +3819,18 @@
   return 0;
 }
 
+static void
+hv_store_str (pTHX_ HV* hv, char *key, U32 len, SV* value)
+{
+  /* Note: not a utf8 hash key */
+#if PERL_VERSION > 8 || (PERL_VERSION == 8 && PERL_SUBVERSION >= 9)
+  hv_common (hv, NULL, key, len, 0,
+             HV_FETCH_ISSTORE|HV_FETCH_JUST_SV, value, 0);
+#else
+  hv_store (hv, key, len, value, 0);
+#endif
+}
+
 static SV *
 decode_hv (pTHX_ dec_t *dec, SV *typesv)
 {
@@ -3802,6 +3841,8 @@
   int allow_squote = dec->json.flags & F_ALLOW_SQUOTE;
   int allow_barekey = dec->json.flags & F_ALLOW_BAREKEY;
   int allow_dupkeys = dec->json.flags & F_ALLOW_DUPKEYS;
+  int dupkeys_as_arrayref = dec->json.flags & F_DUPKEYS_AS_AREF;
+  int dupkeys_first = dec->json.flags & F_DUPKEYS_FIRST;
   char endstr = '"';
 
   DEC_INC_DEPTH;
@@ -3847,24 +3888,43 @@
         {
           SV *value;
           SV *value_typesv = NULL;
+          SV *old_value = NULL;
           char *p = dec->cur;
           char *e = p + 24; /* only try up to 24 bytes */
+          bool key_exists;
 
           for (;;)
             {
               /* the >= 0x80 is false on most architectures */
-              if (!is_bare &&
+              if (UNLIKELY(!is_bare &&
                   (p == e || *p < 0x20 || *(U8*)p >= 0x80 || *p == '\\'
-                   || allow_squote))
+                   || allow_squote)))
                 {
                   /* slow path, back up and use decode_str */
                   /* utf8 hash keys are handled here */
-                  SV *key = _decode_str (aTHX_ dec, endstr);
-                  if (!key)
+                  SV *keysv = _decode_str (aTHX_ dec, endstr);
+                  if (!keysv)
                     goto fail;
 
-                  if (!allow_dupkeys && UNLIKELY(hv_exists_ent (hv, key, 0))) {
-                    ERR ("Duplicate keys not allowed");
+                  key_exists = hv_exists_ent (hv, keysv, 0);
+                  if (UNLIKELY (key_exists)) {
+                    if (!allow_dupkeys)
+                      ERR ("Duplicate keys not allowed");
+                    else if (dupkeys_as_arrayref) {
+                      // extend the value to arrayref or push
+                      old_value = HeVAL(hv_fetch_ent (hv, keysv, 0, 0));
+                      SvREFCNT_inc (old_value);
+                      if (dupkeys_first) {
+                        AV *av = newAV ();
+                        av_extend (av, 2);
+                        if (av_store(av, 0, old_value))
+                          old_value = newRV ((SV*)av);
+                      } else if (SvTYPE (old_value) != SVt_RV &&
+                                 SvTYPE (SvRV (old_value)) != SVt_PVAV) {
+                        // not an AvREF
+                        ERR ("Invalid dupkeys_as_arrayref hash key");
+                      }
+                    } // else overwrite it below
                   }
                   decode_ws (dec); EXPECT_CH (':');
                   decode_ws (dec);
@@ -3872,18 +3932,31 @@
                   if (typesv)
                     {
                       value_typesv = newSV (0);
-                      (void)hv_store_ent (typehv, key, value_typesv, 0);
+                      (void)hv_store_ent (typehv, keysv, value_typesv, 0);
                     }
 
                   value = decode_sv (aTHX_ dec, value_typesv);
                   if (!value)
                     {
-                      SvREFCNT_dec (key);
+                      SvREFCNT_dec (keysv);
                       goto fail;
                     }
 
-                  (void)hv_store_ent (hv, key, value, 0);
-                  SvREFCNT_dec (key);
+                  if (UNLIKELY (key_exists && dupkeys_as_arrayref && 
old_value))
+                    {
+                      av_push ((AV*)SvRV (old_value), value);
+                      (void)hv_store_ent (hv, keysv, old_value, 0);
+                      if (dupkeys_first)
+                        {
+                          dupkeys_first = 0;
+                          dec->json.flags &= ~F_DUPKEYS_FIRST;
+                        }
+                    }
+                  else
+                    {
+                      (void)hv_store_ent (hv, keysv, value, 0);
+                    }
+                  SvREFCNT_dec (keysv);
 
                   break;
                 }
@@ -3895,15 +3968,33 @@
                   /* fast path, got a simple key */
                   char *key = dec->cur;
                   U32 len = p - key;
-                  assert(p >= key && p - key < I32_MAX);
+                  assert(p >= key && (p - key) < I32_MAX);
 #if PTRSIZE >= 8
                   /* hv_store can only handle I32 len, which might overflow */
                   /* perl5 just silently truncates it, cperl panics */
                   if (UNLIKELY(p - key > I32_MAX))
                     ERR ("Hash key too large");
 #endif
-                  if (!allow_dupkeys && UNLIKELY(hv_exists (hv, key, len))) {
-                    ERR ("Duplicate keys not allowed");
+                  key_exists = hv_exists (hv, key, len);
+                  if (UNLIKELY (key_exists)) {
+                    if (!allow_dupkeys)
+                      ERR ("Duplicate keys not allowed");
+                    else if (dupkeys_as_arrayref) {
+                      // extend the value to arrayref or push
+                      SV** rv = hv_fetch (hv, key, len, 0);
+                      old_value = *rv;
+                      SvREFCNT_inc (old_value);
+                      if (dupkeys_first) {
+                        AV *av = newAV ();
+                        av_extend (av, 2);
+                        if (av_store(av, 0, old_value))
+                          old_value = newRV ((SV*)av);
+                      } else if (SvTYPE (old_value) != SVt_RV &&
+                                 SvTYPE (SvRV (old_value)) != SVt_PVAV) {
+                        // not an AvREF
+                        ERR ("Invalid dupkeys_as_arrayref hash key");
+                      }
+                    } // else overwrite it below
                   }
 
                   dec->cur = p + 1;
@@ -3920,16 +4011,23 @@
                   if (!value)
                     goto fail;
 
-                  /* Note: not a utf8 hash key */
-#if PERL_VERSION > 8 || (PERL_VERSION == 8 && PERL_SUBVERSION >= 9)
-                  hv_common (hv, NULL, key, len, 0,
-                             HV_FETCH_ISSTORE|HV_FETCH_JUST_SV, value, 0);
-#else
-                  hv_store (hv, key, len, value, 0);
-#endif
+                  if (UNLIKELY (key_exists && dupkeys_as_arrayref))
+                    {
+                      av_push ((AV*)SvRV (old_value), value);
+                      hv_store_str (aTHX_ hv, key, len, old_value);
+                      if (dupkeys_first)
+                        {
+                          dupkeys_first = 0;
+                          dec->json.flags &= ~F_DUPKEYS_FIRST;
+                        }
+                    }
+                  else
+                    {
+                      /* Note: not a utf8 hash key */
+                      hv_store_str (aTHX_ hv, key, len, value);
+                    }
                   break;
                 }
-
               ++p;
             }
         }
@@ -3986,6 +4084,9 @@
 
               PUTBACK; count = call_sv (HeVAL (cb), G_ARRAY); SPAGAIN;
 
+              if (!json_validate (&dec->json))
+                  croak (NULL);
+
               if (count == 1)
                 {
                   sv = newSVsv (POPs);
@@ -4009,6 +4110,9 @@
 
           PUTBACK; count = call_sv (dec->json.cb_object, G_ARRAY); SPAGAIN;
 
+          if (!json_validate (&dec->json))
+              croak (NULL);
+
           if (count == 1)
             {
               sv = newSVsv (POPs);
@@ -4096,6 +4200,8 @@
     call_sv ((SV *)GvCV (method), G_SCALAR);
     SPAGAIN;
 
+    if (!json_validate (&dec->json))
+        croak (NULL);
     SvREFCNT_dec (tag);
     SvREFCNT_dec (val);
     sv = SvREFCNT_inc (POPs);
@@ -4254,6 +4360,8 @@
   int converted = 0;
   /*dMY_CXT;*/
 
+  if (!json_validate (json))
+      croak (NULL);
   /* work around bugs in 5.10 where manipulating magic values
    * makes perl ignore the magic in subsequent accesses.
    * also make a copy of non-PV values, to get them into a clean
@@ -4627,7 +4735,8 @@
     PPCODE:
         sv = MY_CXT.sv_json;
         MY_CXT.sv_json = NULL;
-        SvREFCNT_dec_NN(sv);
+        if (sv && SvOK (sv))
+            SvREFCNT_dec_NN (sv);
        /* skip implicit PUTBACK, returning @_ to caller, more efficient*/
         return;
 
@@ -4669,11 +4778,16 @@
         allow_dupkeys   = F_ALLOW_DUPKEYS
         require_types   = F_REQUIRE_TYPES
         type_all_string = F_TYPE_ALL_STRING
+        dupkeys_as_arrayref = F_DUPKEYS_AS_AREF
     PPCODE:
         if (enable)
           self->flags |=  ix;
         else
           self->flags &= ~ix;
+        # Turning on DUPKEYS_AS_AREF also turns on ALLOW_DUPKEYS
+        # But turning off DUPKEYS_AS_AREF does not
+        if (ix == F_DUPKEYS_AS_AREF && enable != 0)
+          self->flags |= F_ALLOW_DUPKEYS | F_DUPKEYS_FIRST;
         XPUSHs (ST (0));
 
 void get_ascii (JSON *self)
@@ -4702,6 +4816,7 @@
         get_allow_dupkeys   = F_ALLOW_DUPKEYS
         get_require_types   = F_REQUIRE_TYPES
         get_type_all_string = F_TYPE_ALL_STRING
+        get_dupkeys_as_arrayref = F_DUPKEYS_AS_AREF
     PPCODE:
         XPUSHs (boolSV (self->flags & ix));
 
@@ -4964,9 +5079,7 @@
        CODE:
 {
         if (self->incr_text)
-          {
             SvREFCNT_dec (self->incr_text);
-          }
         self->incr_text = NULL;
         self->incr_pos  = 0;
         self->incr_nest = 0;
@@ -4975,10 +5088,17 @@
 
 void DESTROY (JSON *self)
        CODE:
-        SvREFCNT_dec (self->cb_sk_object);
-        SvREFCNT_dec (self->cb_object);
-        SvREFCNT_dec (self->cb_sort_by);
-        SvREFCNT_dec (self->incr_text);
+        if (!json_validate (self))
+            return;
+        # verify cb_sk_object for a valid HV
+        if (self->cb_sk_object && (SvTYPE (self->cb_sk_object) == SVt_PVHV))
+            SvREFCNT_dec (self->cb_sk_object);
+        if (self->cb_object && SvOK (self->cb_object))
+            SvREFCNT_dec (self->cb_object);
+        if (self->cb_sort_by && SvOK (self->cb_sort_by))
+            SvREFCNT_dec (self->cb_sort_by);
+        if (self->incr_text)
+            SvREFCNT_dec (self->incr_text);
 
 PROTOTYPES: ENABLE
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.27/t/118_type.t 
new/Cpanel-JSON-XS-4.28/t/118_type.t
--- old/Cpanel-JSON-XS-4.27/t/118_type.t        2020-12-14 08:22:05.000000000 
+0100
+++ new/Cpanel-JSON-XS-4.28/t/118_type.t        2022-05-05 16:44:35.000000000 
+0200
@@ -129,7 +129,8 @@
   is($cjson->encode(     -9**9**9, JSON_TYPE_INT), '-2147483648');
 } else {
 SKIP: {
-  skip "unknown ivsize $Config{ivsize}", 26 if $Config{ivsize} != 8;
+  skip "Skip testing ivsize $Config{ivsize}, ivtype $Config{ivtype}", 26
+    if $Config{ivsize} != 8 and $Config{ivtype} ne 'long';
 
   # values around signed IV_MAX should work correctly as they can be 
represented by unsigned UV
   is($cjson->encode( '9223372036854775806', JSON_TYPE_INT),  
'9223372036854775806');  #  2^63-2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.27/t/20_unknown.t 
new/Cpanel-JSON-XS-4.28/t/20_unknown.t
--- old/Cpanel-JSON-XS-4.27/t/20_unknown.t      2020-10-27 18:39:10.000000000 
+0100
+++ new/Cpanel-JSON-XS-4.28/t/20_unknown.t      2022-05-05 16:31:37.000000000 
+0200
@@ -49,9 +49,15 @@
 is( $pp->encode( {null => \""} ),       '{"null":null}',   'pp unknown' );
 # valid special yes/no values even without nonref
 my $e = $pp->encode( {true => !!1} ); # pp is a bit inconsistent
-ok( ($e eq '{"true":"1"}') || ($e eq '{"true":1}'),    'pp sv_yes' );
-is( $pp->encode( {false => !!0} ),      '{"false":""}',    'pp sv_no' );
-is( $pp->encode( {false => !!""} ),     '{"false":""}',    'pp sv_no' );
+if ($] < 5.035010) {
+  ok( ($e eq '{"true":"1"}') || ($e eq '{"true":1}'),        'pp sv_yes' );
+  is( $pp->encode( {false => !!0} ),      '{"false":""}',    'pp sv_no' );
+  is( $pp->encode( {false => !!""} ),     '{"false":""}',    'pp sv_no' );
+} else { # native bool
+  is( $pp->encode( {true => !!1} ),       '{"true":true}',   'pp sv_yes' );
+  is( $pp->encode( {false => !!0} ),      '{"false":false}', 'pp sv_no' );
+  is( $pp->encode( {false => !!""} ),     '{"false":false}', 'pp sv_no' );
+}
 is( $pp->encode( {true => \!!1} ),      '{"true":true}',   'pp \sv_yes');
 is( $pp->encode( {false => \!!0} ),     '{"false":null}',  'pp \sv_no' );
 is( $pp->encode( {false => \!!""} ),    '{"false":null}',  'pp \sv_no' );
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Cpanel-JSON-XS-4.27/t/26_duplicate.t 
new/Cpanel-JSON-XS-4.28/t/26_duplicate.t
--- old/Cpanel-JSON-XS-4.27/t/26_duplicate.t    2020-10-27 18:39:10.000000000 
+0100
+++ new/Cpanel-JSON-XS-4.28/t/26_duplicate.t    2022-05-05 16:44:35.000000000 
+0200
@@ -1,5 +1,5 @@
 use strict;
-use Test::More tests => 9;
+use Test::More tests => 12;
 use Cpanel::JSON::XS;
 
 my $json = Cpanel::JSON::XS->new;
@@ -32,7 +32,18 @@
 eval { $json->decode ('{"a":"b","a":"c"}') }; # the XS slow path
 like ($@, qr/^Duplicate keys not allowed/, 'relaxed and allow_dupkeys(0)');
 
+# allow dupkeys
 $json->allow_dupkeys;
 $json->relaxed(0); # tuning off relaxed needs to turn off dupkeys
 eval { $json->decode ('{"a":"b","a":"c"}') };
 like ($@, qr/^Duplicate keys not allowed/, 'relaxed(0)');
+
+# a private extension (GH #193)
+$json->allow_dupkeys(0);
+$json->dupkeys_as_arrayref; # should turn on dupkeys
+is (encode_json ($json->decode ('{"a":"b","a":"c"}')), '{"a":["b","c"]}',
+    'dupkeys_as_arrayref');
+is (encode_json ($json->decode ('{"a":["b"],"a":"c"}')), '{"a":[["b"],"c"]}',
+    'dupkeys_as_arrayref to []');
+is (encode_json ($json->decode ('{"a":["b","c"],"a":["c"]}')), 
'{"a":[["b","c"],["c"]]}',
+    'dupkeys_as_arrayref to [[]]');

Reply via email to