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 [[]]');