Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-cbor2 for openSUSE:Factory checked in at 2021-04-23 17:50:38 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-cbor2 (Old) and /work/SRC/openSUSE:Factory/.python-cbor2.new.12324 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-cbor2" Fri Apr 23 17:50:38 2021 rev:6 rq:887881 version:5.2.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-cbor2/python-cbor2.changes 2020-08-21 19:17:19.168824687 +0200 +++ /work/SRC/openSUSE:Factory/.python-cbor2.new.12324/python-cbor2.changes 2021-04-23 17:50:55.218824572 +0200 @@ -1,0 +2,12 @@ +Thu Apr 22 20:17:32 UTC 2021 - Dirk M??ller <[email protected]> + +- update to 5.2.0: + * Final version tested with Python 2.7 and 3.5 + * README: Announce deprecation of Python 2.7, 3.5 + * README: More detail and examples + * Bugfix: Fix segfault on loading huge arrays with C-backend (Sekenre) + * Build system: Allow packagers to force C-backend building or disable using env var (jameshilliard) + * Feature: :module:`cbor2.tool` Command line diagnostic tool (Sekenre) + * Feature: Ignore semantic tag used for file magic 55799 AKA "Self-Described CBOR" (kalcutter) + +------------------------------------------------------------------- Old: ---- cbor2-5.1.2.tar.gz New: ---- cbor2-5.2.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-cbor2.spec ++++++ --- /var/tmp/diff_new_pack.fUFMua/_old 2021-04-23 17:50:55.626825273 +0200 +++ /var/tmp/diff_new_pack.fUFMua/_new 2021-04-23 17:50:55.626825273 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-cbor2 # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-cbor2 -Version: 5.1.2 +Version: 5.2.0 Release: 0 Summary: Pure Python CBOR (de)serializer with extensive tag support License: MIT ++++++ cbor2-5.1.2.tar.gz -> cbor2-5.2.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/.travis.yml new/cbor2-5.2.0/.travis.yml --- old/cbor2-5.1.2/.travis.yml 2020-07-21 18:59:30.000000000 +0200 +++ new/cbor2-5.2.0/.travis.yml 2020-09-30 11:59:25.000000000 +0200 @@ -39,11 +39,15 @@ python: "3.7" - stage: test - env: TOXENV=py38 + env: TOXENV=py38-clib python: "3.8" - + + - stage: test + env: TOXENV=py38-noclib + python: "3.8" + - stage: test - env: TOXENV=py38 + env: TOXENV=py38-clib python: "3.8" arch: s390x diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/LICENSE.txt new/cbor2-5.2.0/LICENSE.txt --- old/cbor2-5.1.2/LICENSE.txt 2020-07-21 18:59:30.000000000 +0200 +++ new/cbor2-5.2.0/LICENSE.txt 2020-09-30 11:59:25.000000000 +0200 @@ -1,19 +1,20 @@ -This is the MIT license: http://www.opensource.org/licenses/mit-license.php +The MIT License (MIT) -Copyright (c) Alex Gr??nholm +Copyright (c) 2016 Alex Gr??nholm -Permission is hereby granted, free of charge, to any person obtaining a copy of this -software and associated documentation files (the "Software"), to deal in the Software -without restriction, including without limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -to whom the Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/PKG-INFO new/cbor2-5.2.0/PKG-INFO --- old/cbor2-5.1.2/PKG-INFO 2020-07-21 18:59:46.000000000 +0200 +++ new/cbor2-5.2.0/PKG-INFO 2020-09-30 11:59:41.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: cbor2 -Version: 5.1.2 +Version: 5.2.0 Summary: Pure Python CBOR (de)serializer with extensive tag support Home-page: UNKNOWN Author: Alex Gr??nholm @@ -21,18 +21,111 @@ :target: https://cbor2.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status + About + ===== + + .. warning:: This project will be ending it's support of Python 3.5 and lower with release 6.0.0. Version 5.2 will be the last version tested on Python 2.7 and 3.5 + This library provides encoding and decoding for the Concise Binary Object Representation (CBOR) (`RFC 7049`_) serialization format. `Read the docs <https://cbor2.readthedocs.io/>`_ to learn more. - It is implemented in pure python with an optional C backend and is compatible with versions 2.7 through to 3.7. - - On cPython>=3.3 cbor2 can use a built in C module for performance similar to how ``pickle`` - wraps the ``_pickle`` C module in the Python Standard Library. On Windows, this is restricted to cPython>=3.5. + It is implemented in pure python with an optional C backend. On PyPy, cbor2 runs with almost identical performance to the C backend. .. _RFC 7049: https://tools.ietf.org/html/rfc7049 + Features + -------- + + * Simple api like ``json`` or ``pickle`` modules. + * Support many `CBOR tags`_ with `stdlib objects`_. + * Generic tag decoding. + * `Shared value`_ references including cyclic references. + * Optional C module backend tested on big- and little-endian architectures. + * Extensible `tagged value handling`_ using ``tag_hook`` and ``object_hook`` on decode and ``default`` on encode. + * Command-line diagnostic tool, converting CBOR file or stream to JSON ``python -m cbor2.tool`` + (This is a lossy conversion, for diagnostics only) + * Thorough test suite. + + .. _CBOR tags: https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml + .. _stdlib objects: https://cbor2.readthedocs.io/en/latest/usage.html#tag-support + .. _Shared value: http://cbor.schmorp.de/value-sharing + .. _tagged value handling: https://cbor2.readthedocs.io/en/latest/customizing.html#using-the-cbor-tags-for-custom-types + + Installation + ============ + + :: + + pip install cbor2 + + Requirements + ------------ + + * cPython==2.7 or cPython>=3.5 or `PyPy`_ (Python 2.7 and 3.5 support will be removed with release 6.0.0) + * C-extension: Any C compiler that can build Python extensions. + Any modern libc with the exception of Glibc<2.9 + + .. _PyPy: https://www.pypy.org/ + + Building the C-Extension + ------------------------ + + To force building of the optional C-extension, set OS env ``CBOR2_BUILD_C_EXTENSION=1``. + To disable building of the optional C-extension, set OS env ``CBOR2_BUILD_C_EXTENSION=0``. + If this environment variable is unset, setup.py will default to auto detecting a compatible C library and + attempt to compile the extension. + + + Usage + ===== + + `Basic Usage <https://cbor2.readthedocs.io/en/latest/usage.html#basic-usage>`_ + + Command-line Usage + ================== + + ``python -m cbor2.tool`` converts CBOR data in raw binary or base64 encoding into + a representation that allows printing as JSON. This is a lossy transformation as + each datatype is converted into something that can be represented as a JSON value. + + Usage:: + + # Pass hexadecimal through xxd. + $ echo a16568656c6c6f65776f726c64 | xxd -r -ps | python -m cbor2.tool --pretty + { + "hello": "world" + } + # Decode Base64 directly + $ echo ggEC | python -m cbor2.tool --decode + [1, 2] + # Read from a file encoded in Base64 + $ python -m cbor2.tool -d tests/examples.cbor.b64 + {...} + + It can be used in a pipeline with json processing tools like `jq`_ to allow syntax + coloring, field extraction and more. + + CBOR data items concatenated into a sequence can be decoded also:: + + $ echo ggECggMEggUG | python -m cbor2.tool -d --sequence + [1, 2] + [3, 4] + [5, 6] + + Multiple files can also be sent to a single output file:: + + $ python -m cbor2.tool -o all_files.json file1.cbor file2.cbor ... fileN.cbor + + .. _jq: https://stedolan.github.io/jq/ + + Security + ======== + + This library has not been tested against malicious input. In theory it should be + as safe as JSON, since unlike ``pickle`` the decoder does not execute any code. + Keywords: serialization cbor Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/README.rst new/cbor2-5.2.0/README.rst --- old/cbor2-5.1.2/README.rst 2020-07-21 18:59:30.000000000 +0200 +++ new/cbor2-5.2.0/README.rst 2020-09-30 11:59:25.000000000 +0200 @@ -8,14 +8,107 @@ :target: https://cbor2.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status +About +===== + +.. warning:: This project will be ending it's support of Python 3.5 and lower with release 6.0.0. Version 5.2 will be the last version tested on Python 2.7 and 3.5 + This library provides encoding and decoding for the Concise Binary Object Representation (CBOR) (`RFC 7049`_) serialization format. `Read the docs <https://cbor2.readthedocs.io/>`_ to learn more. -It is implemented in pure python with an optional C backend and is compatible with versions 2.7 through to 3.7. - -On cPython>=3.3 cbor2 can use a built in C module for performance similar to how ``pickle`` -wraps the ``_pickle`` C module in the Python Standard Library. On Windows, this is restricted to cPython>=3.5. +It is implemented in pure python with an optional C backend. On PyPy, cbor2 runs with almost identical performance to the C backend. .. _RFC 7049: https://tools.ietf.org/html/rfc7049 + +Features +-------- + +* Simple api like ``json`` or ``pickle`` modules. +* Support many `CBOR tags`_ with `stdlib objects`_. +* Generic tag decoding. +* `Shared value`_ references including cyclic references. +* Optional C module backend tested on big- and little-endian architectures. +* Extensible `tagged value handling`_ using ``tag_hook`` and ``object_hook`` on decode and ``default`` on encode. +* Command-line diagnostic tool, converting CBOR file or stream to JSON ``python -m cbor2.tool`` + (This is a lossy conversion, for diagnostics only) +* Thorough test suite. + +.. _CBOR tags: https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml +.. _stdlib objects: https://cbor2.readthedocs.io/en/latest/usage.html#tag-support +.. _Shared value: http://cbor.schmorp.de/value-sharing +.. _tagged value handling: https://cbor2.readthedocs.io/en/latest/customizing.html#using-the-cbor-tags-for-custom-types + +Installation +============ + +:: + + pip install cbor2 + +Requirements +------------ + +* cPython==2.7 or cPython>=3.5 or `PyPy`_ (Python 2.7 and 3.5 support will be removed with release 6.0.0) +* C-extension: Any C compiler that can build Python extensions. + Any modern libc with the exception of Glibc<2.9 + +.. _PyPy: https://www.pypy.org/ + +Building the C-Extension +------------------------ + +To force building of the optional C-extension, set OS env ``CBOR2_BUILD_C_EXTENSION=1``. +To disable building of the optional C-extension, set OS env ``CBOR2_BUILD_C_EXTENSION=0``. +If this environment variable is unset, setup.py will default to auto detecting a compatible C library and +attempt to compile the extension. + + +Usage +===== + +`Basic Usage <https://cbor2.readthedocs.io/en/latest/usage.html#basic-usage>`_ + +Command-line Usage +================== + +``python -m cbor2.tool`` converts CBOR data in raw binary or base64 encoding into +a representation that allows printing as JSON. This is a lossy transformation as +each datatype is converted into something that can be represented as a JSON value. + +Usage:: + + # Pass hexadecimal through xxd. + $ echo a16568656c6c6f65776f726c64 | xxd -r -ps | python -m cbor2.tool --pretty + { + "hello": "world" + } + # Decode Base64 directly + $ echo ggEC | python -m cbor2.tool --decode + [1, 2] + # Read from a file encoded in Base64 + $ python -m cbor2.tool -d tests/examples.cbor.b64 + {...} + +It can be used in a pipeline with json processing tools like `jq`_ to allow syntax +coloring, field extraction and more. + +CBOR data items concatenated into a sequence can be decoded also:: + + $ echo ggECggMEggUG | python -m cbor2.tool -d --sequence + [1, 2] + [3, 4] + [5, 6] + +Multiple files can also be sent to a single output file:: + + $ python -m cbor2.tool -o all_files.json file1.cbor file2.cbor ... fileN.cbor + +.. _jq: https://stedolan.github.io/jq/ + +Security +======== + +This library has not been tested against malicious input. In theory it should be +as safe as JSON, since unlike ``pickle`` the decoder does not execute any code. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/cbor2/decoder.py new/cbor2-5.2.0/cbor2/decoder.py --- old/cbor2-5.1.2/cbor2/decoder.py 2020-07-21 18:59:30.000000000 +0200 +++ new/cbor2-5.2.0/cbor2/decoder.py 2020-09-30 11:59:25.000000000 +0200 @@ -276,11 +276,11 @@ else: items.append(value) else: - items = [None] * length + items = [] if not self._immutable: self.set_shareable(items) for index in range(length): - items[index] = self._decode() + items.append(self._decode()) if self._immutable: items = tuple(items) @@ -300,15 +300,6 @@ break else: dictionary[key] = self._decode(unshared=True) - elif self._share_index is None: - # Optimization: pre-allocate structures from length. Note this - # cannot be done when sharing the structure as the resulting - # structure is not the one initially allocated - seq = [None] * length - for index in range(length): - key = self._decode(immutable=True, unshared=True) - seq[index] = (key, self._decode(unshared=True)) - dictionary = dict(seq) else: dictionary = {} self.set_shareable(dictionary) @@ -485,6 +476,10 @@ break raise CBORDecodeValueError("invalid ipnetwork value %r" % net_map) + def decode_self_describe_cbor(self): + # Semantic tag 55799 + return self._decode() + # # Special decoders (major tag 7) # @@ -532,21 +527,22 @@ } semantic_decoders = { - 0: CBORDecoder.decode_datetime_string, - 1: CBORDecoder.decode_epoch_datetime, - 2: CBORDecoder.decode_positive_bignum, - 3: CBORDecoder.decode_negative_bignum, - 4: CBORDecoder.decode_fraction, - 5: CBORDecoder.decode_bigfloat, - 28: CBORDecoder.decode_shareable, - 29: CBORDecoder.decode_sharedref, - 30: CBORDecoder.decode_rational, - 35: CBORDecoder.decode_regexp, - 36: CBORDecoder.decode_mime, - 37: CBORDecoder.decode_uuid, - 258: CBORDecoder.decode_set, - 260: CBORDecoder.decode_ipaddress, - 261: CBORDecoder.decode_ipnetwork, + 0: CBORDecoder.decode_datetime_string, + 1: CBORDecoder.decode_epoch_datetime, + 2: CBORDecoder.decode_positive_bignum, + 3: CBORDecoder.decode_negative_bignum, + 4: CBORDecoder.decode_fraction, + 5: CBORDecoder.decode_bigfloat, + 28: CBORDecoder.decode_shareable, + 29: CBORDecoder.decode_sharedref, + 30: CBORDecoder.decode_rational, + 35: CBORDecoder.decode_regexp, + 36: CBORDecoder.decode_mime, + 37: CBORDecoder.decode_uuid, + 258: CBORDecoder.decode_set, + 260: CBORDecoder.decode_ipaddress, + 261: CBORDecoder.decode_ipnetwork, + 55799: CBORDecoder.decode_self_describe_cbor, } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/cbor2/tool.py new/cbor2-5.2.0/cbor2/tool.py --- old/cbor2-5.1.2/cbor2/tool.py 1970-01-01 01:00:00.000000000 +0100 +++ new/cbor2-5.2.0/cbor2/tool.py 2020-09-30 11:59:25.000000000 +0200 @@ -0,0 +1,225 @@ +r"""Command-line tool for CBOR diagnostics and testing""" +import argparse +import base64 +import decimal +import fractions +import io +import json +import re +import sys +import uuid +from collections import OrderedDict +from datetime import datetime +from functools import partial + +from . import CBORDecoder, load +from .types import FrozenDict + +try: + from _cbor2 import CBORSimpleValue, CBORTag, undefined +except ImportError: + from .types import CBORSimpleValue, CBORTag, undefined + +try: + import ipaddress + + default_encoders = OrderedDict( + [ + (ipaddress.IPv4Address, str), + (ipaddress.IPv6Address, str), + (ipaddress.IPv4Network, str), + (ipaddress.IPv6Network, str), + ] + ) +except ImportError: + default_encoders = OrderedDict() + + +default_encoders.update( + [ + (bytes, lambda x: x.decode(encoding='utf-8', errors='backslashreplace')), + (decimal.Decimal, str), + (FrozenDict, lambda x: str(dict(x))), + (CBORSimpleValue, lambda x: 'cbor_simple:{:d}'.format(x.value)), + (type(undefined), lambda x: 'cbor:undef'), + (datetime, lambda x: x.isoformat()), + (fractions.Fraction, str), + (uuid.UUID, lambda x: x.urn), + (CBORTag, lambda x: {'CBORTag:{:d}'.format(x.tag): x.value}), + (set, list), + (re.compile('').__class__, lambda x: x.pattern), + ] +) + + +def tag_hook(decoder, tag, ignore_tags=set()): + if tag.tag in ignore_tags: + return tag.value + if tag.tag == 24: + return decoder.decode_from_bytes(tag.value) + else: + if decoder.immutable: + return 'CBORtag:{}:{}'.format(tag.tag, tag.value) + return tag + + +class DefaultEncoder(json.JSONEncoder): + def default(self, v): + obj_type = v.__class__ + encoder = default_encoders.get(obj_type) + if encoder: + return encoder(v) + return json.JSONEncoder.default(self, v) + + +def iterdecode(f, *args, **kwargs): + decoder = CBORDecoder(f, *args, **kwargs) + while True: + try: + yield decoder.decode() + except EOFError: + return + + +def key_to_str(d, dict_ids=None): + dict_ids = set(dict_ids or []) + rval = {} + if not isinstance(d, dict): + if isinstance(d, CBORSimpleValue): + v = 'cbor_simple:{:d}'.format(d.value) + return v + if isinstance(d, (tuple, list, set)): + if id(d) in dict_ids: + raise ValueError("Cannot convert self-referential data to JSON") + else: + dict_ids.add(id(d)) + v = [key_to_str(x, dict_ids) for x in d] + dict_ids.remove(id(d)) + return v + else: + return d + + if id(d) in dict_ids: + raise ValueError("Cannot convert self-referential data to JSON") + else: + dict_ids.add(id(d)) + + for k, v in d.items(): + if isinstance(k, bytes): + k = k.decode(encoding='utf-8', errors='backslashreplace') + if isinstance(k, CBORSimpleValue): + k = 'cbor_simple:{:d}'.format(k.value) + if isinstance(k, (FrozenDict, frozenset, tuple)): + k = str(k) + if isinstance(v, dict): + v = key_to_str(v, dict_ids) + elif isinstance(v, (tuple, list, set)): + v = [key_to_str(x, dict_ids) for x in v] + rval[k] = v + return rval + + +def main(): + prog = 'python -m cbor2.tool' + description = ( + 'A simple command line interface for cbor2 module ' + 'to validate and pretty-print CBOR objects.' + ) + parser = argparse.ArgumentParser(prog=prog, description=description) + parser.add_argument( + '-o', '--outfile', type=str, help='output file', default='-' + ) + parser.add_argument( + 'infiles', + nargs='*', + type=argparse.FileType('rb'), + help='Collection of CBOR files to process or - for stdin', + ) + parser.add_argument( + '-k', + '--sort-keys', + action='store_true', + default=False, + help='sort the output of dictionaries alphabetically by key', + ) + parser.add_argument( + '-p', + '--pretty', action='store_true', default=False, help='indent the output to look good' + ) + parser.add_argument( + '-s', + '--sequence', + action='store_true', + default=False, + help='Parse a sequence of concatenated CBOR items', + ) + parser.add_argument( + '-d', + '--decode', + action='store_true', + default=False, + help='CBOR data is base64 encoded (handy for stdin)', + ) + parser.add_argument( + '-i', + '--tag-ignore', + type=str, + help='Comma separated list of tags to ignore and only return the value', + ) + options = parser.parse_args() + + outfile = options.outfile + sort_keys = options.sort_keys + pretty = options.pretty + sequence = options.sequence + decode = options.decode + infiles = options.infiles or [sys.stdin] + + closefd = True + if outfile == '-': + outfile = 1 + closefd = False + + if sys.version_info < (3, 3): + opener = dict(mode='wb', closefd=closefd) + dumpargs = dict(ensure_ascii=True, encoding='raw_unicode_escape') + else: + opener = dict(mode='w', encoding='utf-8', errors='backslashescape', closefd=closefd) + dumpargs = dict(ensure_ascii=False) + + if options.tag_ignore: + ignore_s = options.tag_ignore.split(',') + droptags = set(int(n) for n in ignore_s if (len(n) and n[0].isdigit())) + else: + droptags = set() + + my_hook = partial(tag_hook, ignore_tags=droptags) + + with io.open(outfile, **opener) as outfile: + for infile in infiles: + if hasattr(infile, 'buffer') and not decode: + infile = infile.buffer + with infile: + if decode: + infile = io.BytesIO(base64.b64decode(infile.read())) + try: + if sequence: + objs = iterdecode(infile, tag_hook=my_hook) + else: + objs = (load(infile, tag_hook=my_hook),) + for obj in objs: + json.dump( + key_to_str(obj), + outfile, + sort_keys=sort_keys, + indent=(None, 4)[pretty], + cls=DefaultEncoder, + **dumpargs + ) + outfile.write('\n') + except (ValueError, EOFError) as e: # pragma: no cover + raise SystemExit(e) + + +if __name__ == '__main__': # pragma: no cover + main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/cbor2.egg-info/PKG-INFO new/cbor2-5.2.0/cbor2.egg-info/PKG-INFO --- old/cbor2-5.1.2/cbor2.egg-info/PKG-INFO 2020-07-21 18:59:46.000000000 +0200 +++ new/cbor2-5.2.0/cbor2.egg-info/PKG-INFO 2020-09-30 11:59:41.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: cbor2 -Version: 5.1.2 +Version: 5.2.0 Summary: Pure Python CBOR (de)serializer with extensive tag support Home-page: UNKNOWN Author: Alex Gr??nholm @@ -21,18 +21,111 @@ :target: https://cbor2.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status + About + ===== + + .. warning:: This project will be ending it's support of Python 3.5 and lower with release 6.0.0. Version 5.2 will be the last version tested on Python 2.7 and 3.5 + This library provides encoding and decoding for the Concise Binary Object Representation (CBOR) (`RFC 7049`_) serialization format. `Read the docs <https://cbor2.readthedocs.io/>`_ to learn more. - It is implemented in pure python with an optional C backend and is compatible with versions 2.7 through to 3.7. - - On cPython>=3.3 cbor2 can use a built in C module for performance similar to how ``pickle`` - wraps the ``_pickle`` C module in the Python Standard Library. On Windows, this is restricted to cPython>=3.5. + It is implemented in pure python with an optional C backend. On PyPy, cbor2 runs with almost identical performance to the C backend. .. _RFC 7049: https://tools.ietf.org/html/rfc7049 + Features + -------- + + * Simple api like ``json`` or ``pickle`` modules. + * Support many `CBOR tags`_ with `stdlib objects`_. + * Generic tag decoding. + * `Shared value`_ references including cyclic references. + * Optional C module backend tested on big- and little-endian architectures. + * Extensible `tagged value handling`_ using ``tag_hook`` and ``object_hook`` on decode and ``default`` on encode. + * Command-line diagnostic tool, converting CBOR file or stream to JSON ``python -m cbor2.tool`` + (This is a lossy conversion, for diagnostics only) + * Thorough test suite. + + .. _CBOR tags: https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml + .. _stdlib objects: https://cbor2.readthedocs.io/en/latest/usage.html#tag-support + .. _Shared value: http://cbor.schmorp.de/value-sharing + .. _tagged value handling: https://cbor2.readthedocs.io/en/latest/customizing.html#using-the-cbor-tags-for-custom-types + + Installation + ============ + + :: + + pip install cbor2 + + Requirements + ------------ + + * cPython==2.7 or cPython>=3.5 or `PyPy`_ (Python 2.7 and 3.5 support will be removed with release 6.0.0) + * C-extension: Any C compiler that can build Python extensions. + Any modern libc with the exception of Glibc<2.9 + + .. _PyPy: https://www.pypy.org/ + + Building the C-Extension + ------------------------ + + To force building of the optional C-extension, set OS env ``CBOR2_BUILD_C_EXTENSION=1``. + To disable building of the optional C-extension, set OS env ``CBOR2_BUILD_C_EXTENSION=0``. + If this environment variable is unset, setup.py will default to auto detecting a compatible C library and + attempt to compile the extension. + + + Usage + ===== + + `Basic Usage <https://cbor2.readthedocs.io/en/latest/usage.html#basic-usage>`_ + + Command-line Usage + ================== + + ``python -m cbor2.tool`` converts CBOR data in raw binary or base64 encoding into + a representation that allows printing as JSON. This is a lossy transformation as + each datatype is converted into something that can be represented as a JSON value. + + Usage:: + + # Pass hexadecimal through xxd. + $ echo a16568656c6c6f65776f726c64 | xxd -r -ps | python -m cbor2.tool --pretty + { + "hello": "world" + } + # Decode Base64 directly + $ echo ggEC | python -m cbor2.tool --decode + [1, 2] + # Read from a file encoded in Base64 + $ python -m cbor2.tool -d tests/examples.cbor.b64 + {...} + + It can be used in a pipeline with json processing tools like `jq`_ to allow syntax + coloring, field extraction and more. + + CBOR data items concatenated into a sequence can be decoded also:: + + $ echo ggECggMEggUG | python -m cbor2.tool -d --sequence + [1, 2] + [3, 4] + [5, 6] + + Multiple files can also be sent to a single output file:: + + $ python -m cbor2.tool -o all_files.json file1.cbor file2.cbor ... fileN.cbor + + .. _jq: https://stedolan.github.io/jq/ + + Security + ======== + + This library has not been tested against malicious input. In theory it should be + as safe as JSON, since unlike ``pickle`` the decoder does not execute any code. + Keywords: serialization cbor Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/cbor2.egg-info/SOURCES.txt new/cbor2-5.2.0/cbor2.egg-info/SOURCES.txt --- old/cbor2-5.1.2/cbor2.egg-info/SOURCES.txt 2020-07-21 18:59:46.000000000 +0200 +++ new/cbor2-5.2.0/cbor2.egg-info/SOURCES.txt 2020-09-30 11:59:41.000000000 +0200 @@ -9,6 +9,7 @@ cbor2/compat.py cbor2/decoder.py cbor2/encoder.py +cbor2/tool.py cbor2/types.py cbor2.egg-info/PKG-INFO cbor2.egg-info/SOURCES.txt @@ -39,6 +40,9 @@ source/tags.c source/tags.h tests/conftest.py +tests/examples.cbor.b64 +tests/examples.json tests/test_decoder.py tests/test_encoder.py +tests/test_tool.py tests/test_types.py \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/docs/index.rst new/cbor2-5.2.0/docs/index.rst --- old/cbor2-5.1.2/docs/index.rst 2020-07-21 18:59:30.000000000 +0200 +++ new/cbor2-5.2.0/docs/index.rst 2020-09-30 11:59:25.000000000 +0200 @@ -1,6 +1,5 @@ .. include:: ../README.rst - :start-line: 7 - :end-before: Project links + :start-line: 10 Table of contents ----------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/docs/usage.rst new/cbor2-5.2.0/docs/usage.rst --- old/cbor2-5.1.2/docs/usage.rst 2020-07-21 18:59:30.000000000 +0200 +++ new/cbor2-5.2.0/docs/usage.rst 2020-09-30 11:59:25.000000000 +0200 @@ -72,28 +72,38 @@ In addition to all standard CBOR tags, this library supports many extended tags: -=== ======================================== ==================================================== -Tag Semantics Python type(s) -=== ======================================== ==================================================== -0 Standard date/time string datetime.date / datetime.datetime -1 Epoch-based date/time datetime.date / datetime.datetime -2 Positive bignum int / long -3 Negative bignum int / long -4 Decimal fraction decimal.Decimal -5 Bigfloat decimal.Decimal -28 Mark shared value N/A -29 Reference shared value N/A -30 Rational number fractions.Fraction -35 Regular expression ``_sre.SRE_Pattern`` (result of ``re.compile(...)``) -36 MIME message email.message.Message -37 Binary UUID uuid.UUID -258 Set of unique items set -260 Network address :class:`ipaddress.IPv4Address` (or IPv6) -261 Network prefix :class:`ipaddress.IPv4Network` (or IPv6) -=== ======================================== ==================================================== +===== ======================================== ==================================================== +Tag Semantics Python type(s) +===== ======================================== ==================================================== +0 Standard date/time string datetime.date / datetime.datetime +1 Epoch-based date/time datetime.date / datetime.datetime +2 Positive bignum int / long +3 Negative bignum int / long +4 Decimal fraction decimal.Decimal +5 Bigfloat decimal.Decimal +28 Mark shared value N/A +29 Reference shared value N/A +30 Rational number fractions.Fraction +35 Regular expression ``_sre.SRE_Pattern`` (result of ``re.compile(...)``) +36 MIME message email.message.Message +37 Binary UUID uuid.UUID +258 Set of unique items set +260 Network address :class:`ipaddress.IPv4Address` (or IPv6) +261 Network prefix :class:`ipaddress.IPv4Network` (or IPv6) +55799 Self-Described CBOR object +===== ======================================== ==================================================== Arbitary tags can be represented with the :class:`~cbor2.types.CBORTag` class. +If you want to write a file that is detected as CBOR by the Unix ``file`` utility, wrap your data in +a `~cbor2.types.CBORTag` object like so:: + + from cbor2 import dump, CBORTag + + with open('output.cbor', 'wb') as fp: + dump(CBORTag(55799, obj), fp) + +This will be ignored on decode and the original data content will be returned. Use Cases --------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/docs/versionhistory.rst new/cbor2-5.2.0/docs/versionhistory.rst --- old/cbor2-5.1.2/docs/versionhistory.rst 2020-07-21 18:59:30.000000000 +0200 +++ new/cbor2-5.2.0/docs/versionhistory.rst 2020-09-30 11:59:25.000000000 +0200 @@ -5,6 +5,15 @@ This library adheres to `Semantic Versioning <http://semver.org/>`_. +**5.2.0** (2020-09-30) + +- Final version tested with Python 2.7 and 3.5 +- README: Announce deprecation of Python 2.7, 3.5 +- README: More detail and examples +- Bugfix: Fix segfault on loading huge arrays with C-backend (Sekenre) +- Build system: Allow packagers to force C-backend building or disable using env var (jameshilliard) +- Feature: :module:`cbor2.tool` Command line diagnostic tool (Sekenre) +- Feature: Ignore semantic tag used for file magic 55799 AKA "Self-Described CBOR" (kalcutter) **5.1.2** (2020-07-21) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/setup.py new/cbor2-5.2.0/setup.py --- old/cbor2-5.1.2/setup.py 2020-07-21 18:59:30.000000000 +0200 +++ new/cbor2-5.2.0/setup.py 2020-09-30 11:59:25.000000000 +0200 @@ -1,11 +1,15 @@ import sys import os import platform +import warnings from pkg_resources import parse_version from setuptools import setup, Extension min_glibc = parse_version('2.9') +if sys.version_info < (3, 6): + warnings.warn("Support for Python<3.6 will be dropped with cbor2 version 6.0.0") + def check_libc(): "check that if we have glibc < 2.9 we should not build c ext" @@ -27,7 +31,13 @@ windows = sys.platform.startswith('win') min_win_version = sys.version_info >= (3, 5) min_unix_version = sys.version_info >= (3, 3) -build_c_ext = cpython and ((windows and min_win_version) or (check_libc() and min_unix_version)) +use_c_ext = os.environ.get("CBOR2_BUILD_C_EXTENSION", None) +if use_c_ext == "1": + build_c_ext = True +elif use_c_ext == "0": + build_c_ext = False +else: + build_c_ext = cpython and ((windows and min_win_version) or (check_libc() and min_unix_version)) # Enable GNU features for libc's like musl, should have no effect # on Apple/BSDs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/source/decoder.c new/cbor2-5.2.0/source/decoder.c --- old/cbor2-5.1.2/source/decoder.c 2020-07-21 18:59:30.000000000 +0200 +++ new/cbor2-5.2.0/source/decoder.c 2020-09-30 11:59:25.000000000 +0200 @@ -61,6 +61,7 @@ static PyObject * CBORDecoder_decode_float64(CBORDecoderObject *); static PyObject * CBORDecoder_decode_ipaddress(CBORDecoderObject *); static PyObject * CBORDecoder_decode_ipnetwork(CBORDecoderObject *); +static PyObject * CBORDecoder_decode_self_describe_cbor(CBORDecoderObject *); static PyObject * CBORDecoder_decode_shareable(CBORDecoderObject *); static PyObject * CBORDecoder_decode_sharedref(CBORDecoderObject *); @@ -344,7 +345,7 @@ obj = PyObject_CallFunctionObjArgs(self->read, size_obj, NULL); if (obj) { assert(PyBytes_CheckExact(obj)); - if (PyBytes_GET_SIZE(obj) == size) { + if (PyBytes_GET_SIZE(obj) == (Py_ssize_t) size) { data = PyBytes_AS_STRING(obj); memcpy(buf, data, size); ret = 0; @@ -698,55 +699,94 @@ static PyObject * -decode_definite_array(CBORDecoderObject *self, uint64_t length) +decode_definite_array(CBORDecoderObject *self, Py_ssize_t length) { Py_ssize_t i; PyObject *array, *item, *ret = NULL; - if (length > PY_SSIZE_T_MAX) { + if (length > PY_SSIZE_T_MAX || length < 0) { PyErr_Format( _CBOR2_CBORDecodeValueError, "excessive array size %llu", length); return NULL; - } - if (self->immutable) { - array = PyTuple_New(length); + } else if (length > 65536) { + // Let cPython manage allocation of huge lists by appending + // items one-by-one + array = PyList_New(0); if (array) { ret = array; - for (i = 0; i < (Py_ssize_t) length; ++i) { + set_shareable(self, array); + for (i = 0; i < length; ++i) { item = decode(self, DECODE_UNSHARED); - if (item) - PyTuple_SET_ITEM(array, i, item); - else { + if (item) { + if (PyList_Append(array, item) == -1) { + ret = NULL; + Py_DECREF(item); + break; + } + Py_DECREF(item); + } else { ret = NULL; break; } } + if (ret && self->immutable) { + ret = PyList_AsTuple(array); + if (ret) { + Py_DECREF(array); + // There's a potential here for an indefinite length recursive + // array to wind up with a strange representation (the outer + // being a tuple, the inners all being a list). However, a + // recursive tuple isn't valid in the first place so it's a bit + // of a waste of time searching for recursive references just + // to throw an error + set_shareable(self, ret); + } else + ret = NULL; + } + if (!ret) + Py_DECREF(array); } - // This is done *after* the construction of the tuple because while - // it's valid for a tuple object to be shared, it's not valid for it to - // contain a reference to itself (because a reference to it can't exist - // during its own construction ... in Python at least; as can be seen - // above this *is* theoretically possible at the C level). - set_shareable(self, ret); } else { - array = PyList_New(length); - if (array) { - ret = array; - set_shareable(self, array); - for (i = 0; i < (Py_ssize_t) length; ++i) { - item = decode(self, DECODE_UNSHARED); - if (item) - PyList_SET_ITEM(array, i, item); - else { - ret = NULL; - break; + if (self->immutable) { + array = PyTuple_New(length); + if (array) { + ret = array; + for (i = 0; i < length; ++i) { + item = decode(self, DECODE_UNSHARED); + if (item) + PyTuple_SET_ITEM(array, i, item); + else { + ret = NULL; + break; + } + } + } + // This is done *after* the construction of the tuple because while + // it's valid for a tuple object to be shared, it's not valid for it to + // contain a reference to itself (because a reference to it can't exist + // during its own construction ... in Python at least; as can be seen + // above this *is* theoretically possible at the C level). + set_shareable(self, ret); + } else { + array = PyList_New(length); + if (array) { + ret = array; + set_shareable(self, array); + for (i = 0; i < length; ++i) { + item = decode(self, DECODE_UNSHARED); + if (item) + PyList_SET_ITEM(array, i, item); + else { + ret = NULL; + break; + } } } } + if (!ret) + Py_DECREF(array); } - if (!ret) - Py_DECREF(array); return ret; } @@ -763,7 +803,7 @@ if (indefinite) return decode_indefinite_array(self); else - return decode_definite_array(self, length); + return decode_definite_array(self, (Py_ssize_t) length); } @@ -851,21 +891,24 @@ if (decode_length(self, subtype, &tagnum, NULL) == 0) { switch (tagnum) { - case 0: ret = CBORDecoder_decode_datetime_string(self); break; - case 1: ret = CBORDecoder_decode_epoch_datetime(self); break; - case 2: ret = CBORDecoder_decode_positive_bignum(self); break; - case 3: ret = CBORDecoder_decode_negative_bignum(self); break; - case 4: ret = CBORDecoder_decode_fraction(self); break; - case 5: ret = CBORDecoder_decode_bigfloat(self); break; - case 28: ret = CBORDecoder_decode_shareable(self); break; - case 29: ret = CBORDecoder_decode_sharedref(self); break; - case 30: ret = CBORDecoder_decode_rational(self); break; - case 35: ret = CBORDecoder_decode_regexp(self); break; - case 36: ret = CBORDecoder_decode_mime(self); break; - case 37: ret = CBORDecoder_decode_uuid(self); break; - case 258: ret = CBORDecoder_decode_set(self); break; - case 260: ret = CBORDecoder_decode_ipaddress(self); break; - case 261: ret = CBORDecoder_decode_ipnetwork(self); break; + case 0: ret = CBORDecoder_decode_datetime_string(self); break; + case 1: ret = CBORDecoder_decode_epoch_datetime(self); break; + case 2: ret = CBORDecoder_decode_positive_bignum(self); break; + case 3: ret = CBORDecoder_decode_negative_bignum(self); break; + case 4: ret = CBORDecoder_decode_fraction(self); break; + case 5: ret = CBORDecoder_decode_bigfloat(self); break; + case 28: ret = CBORDecoder_decode_shareable(self); break; + case 29: ret = CBORDecoder_decode_sharedref(self); break; + case 30: ret = CBORDecoder_decode_rational(self); break; + case 35: ret = CBORDecoder_decode_regexp(self); break; + case 36: ret = CBORDecoder_decode_mime(self); break; + case 37: ret = CBORDecoder_decode_uuid(self); break; + case 258: ret = CBORDecoder_decode_set(self); break; + case 260: ret = CBORDecoder_decode_ipaddress(self); break; + case 261: ret = CBORDecoder_decode_ipnetwork(self); break; + case 55799: ret = CBORDecoder_decode_self_describe_cbor(self); + break; + default: tag = CBORTag_New(tagnum); if (tag) { @@ -1398,6 +1441,15 @@ return ret; } + +// CBORDecoder.decode_self_describe_cbor(self) +static PyObject * +CBORDecoder_decode_self_describe_cbor(CBORDecoderObject *self) +{ + // semantic tag 55799 + return decode(self, DECODE_NORMAL); +} + // Special decoders ////////////////////////////////////////////////////////// @@ -1690,6 +1742,10 @@ "decode a set or frozenset from the input"}, {"decode_ipaddress", (PyCFunction) CBORDecoder_decode_ipaddress, METH_NOARGS, "decode an IPv4Address or IPv6Address from the input"}, + {"decode_ipnetwork", (PyCFunction) CBORDecoder_decode_ipnetwork, METH_NOARGS, + "decode an IPv4Network or IPv6Network from the input"}, + {"decode_self_describe_cbor", (PyCFunction) CBORDecoder_decode_self_describe_cbor, METH_NOARGS, + "decode a data item after a self-describe CBOR tag"}, {"decode_simple_value", (PyCFunction) CBORDecoder_decode_simple_value, METH_NOARGS, "decode a CBORSimpleValue from the input"}, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/tests/examples.cbor.b64 new/cbor2-5.2.0/tests/examples.cbor.b64 --- old/cbor2-5.1.2/tests/examples.cbor.b64 1970-01-01 01:00:00.000000000 +0100 +++ new/cbor2-5.2.0/tests/examples.cbor.b64 2020-09-30 11:59:25.000000000 +0200 @@ -0,0 +1,12 @@ +s2VieXRlc4NARAECAwRCwsJoZGVjaW1hbHOFxIIiGTcrxIIiOTcq+X4A+XwA+fwAaGRpY3Rfa2V5 +gaGhAgFgZmZsb2F0c4b7P/GZmZmZmZr7fjfkPIgAdZz7wBBmZmZmZmb5fAD5fgD5/ABoZnJhY3Rp +b26B2B6CAgVoaW50ZWdlcnORAAEKFxgYGGQZA+gaAA9CQBsAAADo1KUQABv//////////8JJAQAA +AAAAAAAAO///////////w0kBAAAAAAAAAAAgKThjOQPnZmlwYWRkcoLZAQREwAoKAdkBBFAgAQ24 +haMAAAAAii4DcHM0ZWlwbmV0gtkBBaFEwKgAABgY2QEFoVAgAQ24haMAAAAAii4AAAAAGGBlcmVn +ZXiB2CNtaGVsbG8gKHdvcmxkKWdzaW1wbGVzhODi8/ggaHNwZWNpYWxzhPT19vdnc3RyaW5nc4Zg +YWFkSUVURmIiXGLDvGPmsLRmdGFnZ2VkgdkXcGVIZWxsb2p0aW1lc3RhbXBzh8B0MjAxMy0wMy0y +MVQyMDowNDowMFrAeBsyMDEzLTAzLTIxVDIwOjA0OjAwLjM4MDg0MVrAeBkyMDEzLTAzLTIxVDIy +OjA0OjAwKzAyOjAwwHQyMDEzLTAzLTIxVDIwOjA0OjAwWsB0MjAxMy0wMy0yMVQyMDowNDowMFrA +eBsyMDEzLTAzLTIxVDIwOjA0OjAwLjEyMzQ1NlrAdDIwMTMtMDMtMjFUMjA6MDQ6MDBaaXR1cGxl +X2tleYGhggIBYGR1dWlkgdglUF6v+si1HkgFgSd/3MeEL69qc2ltcGxlX2tleYGh+GP2anRhZ19h +c19rZXmBodkXd2xub3RpbXBvcnRhbnT2aGVtYmVkZGVkgdgYSYRhYWFiYWNhZA== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/tests/examples.json new/cbor2-5.2.0/tests/examples.json --- old/cbor2-5.1.2/tests/examples.json 1970-01-01 01:00:00.000000000 +0100 +++ new/cbor2-5.2.0/tests/examples.json 2020-09-30 11:59:25.000000000 +0200 @@ -0,0 +1,120 @@ +{ + "bytes": [ + "", + "\u0001\u0002\u0003\u0004", + "\\xc2\\xc2" + ], + "decimals": [ + "14.123", + "-14.123", + NaN, + Infinity, + -Infinity + ], + "dict_key": [ + { + "FrozenDict({2: 1})": "" + } + ], + "embedded": [ + [ + "a", + "b", + "c", + "d" + ] + ], + "floats": [ + 1.1, + 1e+300, + -4.1, + Infinity, + NaN, + -Infinity + ], + "fraction": [ + "2/5" + ], + "integers": [ + 0, + 1, + 10, + 23, + 24, + 100, + 1000, + 1000000, + 1000000000000, + 18446744073709551615, + 18446744073709551616, + -18446744073709551616, + -18446744073709551617, + -1, + -10, + -100, + -1000 + ], + "ipaddr": [ + "192.10.10.1", + "2001:db8:85a3::8a2e:370:7334" + ], + "ipnet": [ + "192.168.0.0/24", + "2001:db8:85a3::8a2e:0:0/96" + ], + "regex": [ + "hello (world)" + ], + "simple_key": [ + { + "cbor_simple:99": null + } + ], + "simples": [ + "cbor_simple:0", + "cbor_simple:2", + "cbor_simple:19", + "cbor_simple:32" + ], + "specials": [ + false, + true, + null, + "cbor:undef" + ], + "strings": [ + "", + "a", + "IETF", + "\"\\", + "??", + "???" + ], + "tag_as_key": [ + { + "CBORtag:6007:notimportant": null + } + ], + "tagged": [ + { + "CBORTag:6000": "Hello" + } + ], + "timestamps": [ + "2013-03-21T20:04:00+00:00", + "2013-03-21T20:04:00.380841+00:00", + "2013-03-21T22:04:00+02:00", + "2013-03-21T20:04:00+00:00", + "2013-03-21T20:04:00+00:00", + "2013-03-21T20:04:00.123456+00:00", + "2013-03-21T20:04:00+00:00" + ], + "tuple_key": [ + { + "(2, 1)": "" + } + ], + "uuid": [ + "urn:uuid:5eaffac8-b51e-4805-8127-7fdcc7842faf" + ] +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/tests/test_decoder.py new/cbor2-5.2.0/tests/test_decoder.py --- old/cbor2-5.1.2/tests/test_decoder.py 2020-07-21 18:59:30.000000000 +0200 +++ new/cbor2-5.2.0/tests/test_decoder.py 2020-09-30 11:59:25.000000000 +0200 @@ -501,10 +501,7 @@ def test_uninitialized_shared_reference(impl): with pytest.raises(impl.CBORDecodeError) as exc: - # encode a set of a recursive array; the set forces the embedded array - # to be decoded as a recursive tuple which is impossible, and leads to - # the expected error - impl.loads(unhexlify('d90102d81c81d81d00')) + impl.loads(unhexlify('D81CA1D81D014161')) assert str(exc.value).endswith('shared value 0 has not been initialized') assert isinstance(exc, ValueError) @@ -531,6 +528,14 @@ assert decoded == {0: decoded} [email protected]('payload, expected', [ + ('d9d9f71903e8', 1000), + ('d9d9f7c249010000000000000000', 18446744073709551616), +], ids=['self_describe_cbor+int', 'self_describe_cbor+positive_bignum']) +def test_self_describe_cbor(impl, payload, expected): + assert impl.loads(unhexlify(payload)) == expected + + def test_unhandled_tag(impl): """ Test that a tag is simply ignored and its associated value returned if there is no special @@ -626,3 +631,18 @@ def test_immutable_keys(impl, payload, expected): value = impl.loads(unhexlify(payload)) assert value == expected + + +def test_huge_truncated_array(impl): + with pytest.raises(impl.CBORDecodeEOF): + impl.loads(unhexlify('9b37388519251ae9ca')) + + +def test_huge_truncated_bytes(impl): + with pytest.raises((impl.CBORDecodeEOF, MemoryError)): + impl.loads(unhexlify('5b37388519251ae9ca')) + + +def test_huge_truncated_string(impl): + with pytest.raises((impl.CBORDecodeEOF, MemoryError)): + impl.loads(unhexlify('7B37388519251ae9ca')) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/tests/test_tool.py new/cbor2-5.2.0/tests/test_tool.py --- old/cbor2-5.1.2/tests/test_tool.py 1970-01-01 01:00:00.000000000 +0100 +++ new/cbor2-5.2.0/tests/test_tool.py 2020-09-30 11:59:25.000000000 +0200 @@ -0,0 +1,140 @@ +from __future__ import unicode_literals +import pytest +import sys +import binascii +import json +from io import BytesIO, TextIOWrapper + +import cbor2.tool + + [email protected]( + 'value, expected', + [ + ((1, 2, 3), [1, 2, 3]), + ({b"\x01\x02\x03": "b"}, {"\x01\x02\x03": "b"}), + ({"dict": {"b": 17}}, {"dict": {"b": 17}}), + ], + ids=['tuple', 'byte_key', 'recursion'], +) +def test_key_to_str(value, expected): + assert cbor2.tool.key_to_str(value) == expected + + +def test_default(): + with pytest.raises(TypeError): + json.dumps(BytesIO(b''), cls=cbor2.tool.DefaultEncoder) + + [email protected]( + 'payload', ["D81CA16162D81CA16161D81D00", "d81c81d81c830102d81d00"], ids=['dict', 'list'] +) +def test_self_referencing(payload): + decoded = cbor2.loads(binascii.unhexlify(payload)) + with pytest.raises(ValueError, match="Cannot convert self-referential data to JSON"): + cbor2.tool.key_to_str(decoded) + + +def test_nonrecursive_ref(): + payload = 'd81c83d81ca26162d81ca16161016163d81d02d81d01d81d01' + decoded = cbor2.loads(binascii.unhexlify(payload)) + result = cbor2.tool.key_to_str(decoded) + expected = [ + {"b": {"a": 1}, "c": {"a": 1}}, + {"b": {"a": 1}, "c": {"a": 1}}, + {"b": {"a": 1}, "c": {"a": 1}}, + ] + assert result == expected + + +def test_stdin(monkeypatch, tmpdir): + f = tmpdir.join('outfile') + argv = ['-o', str(f)] + inbuf = TextIOWrapper(BytesIO(binascii.unhexlify('02'))) + with monkeypatch.context() as m: + m.setattr('sys.argv', [''] + argv) + m.setattr('sys.stdin', inbuf) + cbor2.tool.main() + assert f.read() == '2\n' + + +def test_stdout(monkeypatch, tmpdir): + argv = ['-o', '-'] + inbuf = TextIOWrapper(BytesIO(binascii.unhexlify('02'))) + outbuf = BytesIO() + with monkeypatch.context() as m: + m.setattr('sys.argv', [''] + argv) + m.setattr('sys.stdin', inbuf) + m.setattr('sys.stdout', outbuf) + cbor2.tool.main() + + +def test_readfrom(monkeypatch, tmpdir): + f = tmpdir.join('infile') + outfile = tmpdir.join('outfile') + f.write_binary(binascii.unhexlify('02')) + argv = ['-o', str(outfile), str(f)] + with monkeypatch.context() as m: + m.setattr('sys.argv', [''] + argv) + cbor2.tool.main() + assert outfile.read() == '2\n' + + +def test_b64(monkeypatch, tmpdir): + f = tmpdir.join('outfile') + argv = ['-d', '-o', str(f)] + inbuf = TextIOWrapper(BytesIO(b'oQID')) + with monkeypatch.context() as m: + m.setattr('sys.argv', [''] + argv) + m.setattr('sys.stdin', inbuf) + cbor2.tool.main() + assert f.read() == '{"2": 3}\n' + + +def test_stream(monkeypatch, tmpdir): + f = tmpdir.join('outfile') + argv = ['--sequence', '-o', str(f)] + inbuf = TextIOWrapper(BytesIO(binascii.unhexlify('0203'))) + with monkeypatch.context() as m: + m.setattr('sys.argv', [''] + argv) + m.setattr('sys.stdin', inbuf) + cbor2.tool.main() + assert f.read() == '2\n3\n' + + +def test_embed_bytes(monkeypatch, tmpdir): + f = tmpdir.join('outfile') + argv = ['-o', str(f)] + inbuf = TextIOWrapper(BytesIO(binascii.unhexlify('42C2C2'))) + expected = b'"\\u00c2\\u00c2"\n' if sys.version_info < (3, 3) else '"\\\\xc2\\\\xc2"\n' + with monkeypatch.context() as m: + m.setattr('sys.argv', [''] + argv) + m.setattr('sys.stdin', inbuf) + cbor2.tool.main() + assert f.read() == expected + + [email protected]( + sys.version_info < (3, 3), reason="Requires CPython > 3.3" +) +def test_dtypes_from_file(monkeypatch, tmpdir): + infile = 'tests/examples.cbor.b64' + expected = open('tests/examples.json', 'r').read() + outfile = tmpdir.join('outfile.json') + argv = ['--sort-keys', '--pretty', '-d', '-o', str(outfile), infile] + with monkeypatch.context() as m: + m.setattr('sys.argv', [''] + argv) + cbor2.tool.main() + assert outfile.read() == expected + + +def test_ignore_tag(monkeypatch, tmpdir): + f = tmpdir.join('outfile') + argv = ['-o', str(f), '-i', '6000'] + inbuf = TextIOWrapper(BytesIO(binascii.unhexlify('D917706548656C6C6F'))) + expected = '"Hello"\n' + with monkeypatch.context() as m: + m.setattr('sys.argv', [''] + argv) + m.setattr('sys.stdin', inbuf) + cbor2.tool.main() + assert f.read() == expected diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cbor2-5.1.2/tox.ini new/cbor2-5.2.0/tox.ini --- old/cbor2-5.1.2/tox.ini 2020-07-21 18:59:30.000000000 +0200 +++ new/cbor2-5.2.0/tox.ini 2020-09-30 11:59:25.000000000 +0200 @@ -1,5 +1,5 @@ [tox] -envlist = py27, py35, py36, py37, py38, pypy, pypy3, flake8 +envlist = py27, py35, py36, py37, py38-clib, py38-noclib, pypy, pypy3, flake8 skip_missing_interpreters = true [testenv] @@ -10,3 +10,11 @@ deps = flake8 commands = flake8 cbor2 tests skip_install = true + +[testenv:py38-clib] +setenv = + CBOR2_BUILD_C_EXTENSION = 1 + +[testenv:py38-noclib] +setenv = + CBOR2_BUILD_C_EXTENSION = 0
