aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2019-02-01 22:22:43 -0800
committerHaibo Huang <hhb@google.com>2019-07-10 00:46:29 +0000
commitb6b288ecdce6a5774783feafdaeb32e3385628b5 (patch)
tree8d72e5105bf5ea4c099e7b74d303cb50efe57b66
parente35592b4edbd176c68ebd6e53ad8825cceb064cf (diff)
parentdf6fc9a8aae16e32f60a1ff1f42a52c8c344a993 (diff)
downloadpyasn1-b6b288ecdce6a5774783feafdaeb32e3385628b5.tar.gz
Upgrade python/pyasn1 to v0.4.5
Exempt-From-Owner-Approval: Upgrade library Test: build Change-Id: I879edd58806f3b9b7fbf8cc78d02c684b5b336ae
-rw-r--r--.travis.yml59
-rw-r--r--CHANGES.rst20
-rw-r--r--LICENSE.rst2
-rw-r--r--METADATA13
-rw-r--r--README.md4
-rw-r--r--docs/source/conf.py2
-rw-r--r--docs/source/example-use-case.rst4
-rw-r--r--docs/source/pyasn1/contents.rst2
-rw-r--r--pyasn1/__init__.py2
-rw-r--r--pyasn1/codec/ber/decoder.py310
-rw-r--r--pyasn1/codec/ber/encoder.py204
-rw-r--r--pyasn1/codec/ber/eoo.py2
-rw-r--r--pyasn1/codec/cer/decoder.py2
-rw-r--r--pyasn1/codec/cer/encoder.py4
-rw-r--r--pyasn1/codec/der/decoder.py2
-rw-r--r--pyasn1/codec/der/encoder.py2
-rw-r--r--pyasn1/codec/native/decoder.py21
-rw-r--r--pyasn1/codec/native/encoder.py51
-rw-r--r--pyasn1/compat/binary.py2
-rw-r--r--pyasn1/compat/calling.py2
-rw-r--r--pyasn1/compat/dateandtime.py2
-rw-r--r--pyasn1/compat/integer.py2
-rw-r--r--pyasn1/compat/octets.py2
-rw-r--r--pyasn1/compat/string.py2
-rw-r--r--pyasn1/debug.py48
-rw-r--r--pyasn1/error.py4
-rw-r--r--pyasn1/type/base.py14
-rw-r--r--pyasn1/type/char.py2
-rw-r--r--pyasn1/type/constraint.py4
-rw-r--r--pyasn1/type/error.py2
-rw-r--r--pyasn1/type/namedtype.py18
-rw-r--r--pyasn1/type/namedval.py2
-rw-r--r--pyasn1/type/opentype.py2
-rw-r--r--pyasn1/type/tag.py2
-rw-r--r--pyasn1/type/tagmap.py2
-rw-r--r--pyasn1/type/univ.py8
-rw-r--r--pyasn1/type/useful.py2
-rw-r--r--setup.py3
-rw-r--r--tests/__main__.py2
-rw-r--r--tests/base.py2
-rw-r--r--tests/codec/__main__.py2
-rw-r--r--tests/codec/ber/__main__.py2
-rw-r--r--tests/codec/ber/test_decoder.py18
-rw-r--r--tests/codec/ber/test_encoder.py6
-rw-r--r--tests/codec/cer/__main__.py2
-rw-r--r--tests/codec/cer/test_decoder.py2
-rw-r--r--tests/codec/cer/test_encoder.py2
-rw-r--r--tests/codec/der/__main__.py2
-rw-r--r--tests/codec/der/test_decoder.py2
-rw-r--r--tests/codec/der/test_encoder.py2
-rw-r--r--tests/codec/native/__main__.py2
-rw-r--r--tests/codec/native/test_decoder.py2
-rw-r--r--tests/codec/native/test_encoder.py2
-rw-r--r--tests/compat/__main__.py2
-rw-r--r--tests/compat/test_binary.py2
-rw-r--r--tests/compat/test_integer.py2
-rw-r--r--tests/compat/test_octets.py2
-rw-r--r--tests/test_debug.py2
-rw-r--r--tests/type/__main__.py2
-rw-r--r--tests/type/test_char.py2
-rw-r--r--tests/type/test_constraint.py5
-rw-r--r--tests/type/test_namedtype.py2
-rw-r--r--tests/type/test_namedval.py2
-rw-r--r--tests/type/test_opentype.py2
-rw-r--r--tests/type/test_tag.py10
-rw-r--r--tests/type/test_univ.py20
-rw-r--r--tests/type/test_useful.py2
67 files changed, 681 insertions, 257 deletions
diff --git a/.travis.yml b/.travis.yml
index d87a749..3152686 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,16 +1,51 @@
-
language: python
-python:
- - "2.6"
- - "2.7"
- - "3.2"
- - "3.3"
- - "3.4"
- - "3.5"
- - "3.6"
- - "nightly"
- - "pypy"
- - "pypy3"
+cache: pip
+matrix:
+ include:
+ - os: linux
+ dist: trusty
+ sudo: false
+ python: '2.6'
+ - os: linux
+ dist: trusty
+ sudo: false
+ python: '2.7'
+ - os: linux
+ dist: trusty
+ sudo: false
+ python: '3.2'
+ - os: linux
+ dist: trusty
+ sudo: false
+ python: '3.3'
+ - os: linux
+ dist: trusty
+ sudo: false
+ python: '3.4'
+ - os: linux
+ dist: trusty
+ sudo: false
+ python: '3.5'
+ - os: linux
+ dist: trusty
+ sudo: false
+ python: '3.6'
+ - os: linux
+ dist: xenial
+ sudo: true
+ python: '3.7'
+ - os: linux
+ dist: trusty
+ sudo: true
+ python: 'nightly'
+ - os: linux
+ dist: trusty
+ sudo: false
+ python: 'pypy'
+ - os: linux
+ dist: trusty
+ sudo: false
+ python: 'pypy3'
install:
- pip install codecov
- pip install -r requirements.txt -r devel-requirements.txt
diff --git a/CHANGES.rst b/CHANGES.rst
index e72e35a..c4084f3 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,4 +1,24 @@
+Revision 0.4.5, released 29-12-2018
+-----------------------------------
+
+- Debug logging refactored for more efficiency when disabled and
+ for more functionality when in use. Specifically, the global
+ LOG object can easily be used from any function/method, not just
+ from codec main loop as it used to be.
+- More debug logging added to BER family of codecs to ease encoding
+ problems troubleshooting.
+- Copyright notice extended to the year 2019
+- Fixed defaulted constructed SEQUENCE component initialization.
+
+Revision 0.4.4, released 26-07-2018
+-----------------------------------
+
+- Fixed native encoder type map to include all ASN.1 types
+ rather than just ambiguous ones
+- Fixed crash in `.prettyPrint` of `Sequence` and `Set` occurring
+ at OPTIONAL components
+
Revision 0.4.3, released 23-05-2018
-----------------------------------
diff --git a/LICENSE.rst b/LICENSE.rst
index 011bb08..ac630e8 100644
--- a/LICENSE.rst
+++ b/LICENSE.rst
@@ -1,4 +1,4 @@
-Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/METADATA b/METADATA
index 3cd6f97..d6b27fa 100644
--- a/METADATA
+++ b/METADATA
@@ -1,7 +1,5 @@
name: "pyasn1"
-description:
- "ASN.1 types and codecs"
-
+description: "ASN.1 types and codecs"
third_party {
url {
type: HOMEPAGE
@@ -11,6 +9,11 @@ third_party {
type: GIT
value: "https://github.com/etingof/pyasn1"
}
- version: "0.4.3"
- last_upgrade_date { year: 2018 month: 5 day: 23 }
+ version: "v0.4.5"
+ last_upgrade_date {
+ year: 2019
+ month: 2
+ day: 1
+ }
}
+
diff --git a/README.md b/README.md
index fe5ad9a..e36324b 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ Features
* Generic implementation of ASN.1 types (X.208)
* Standards compliant BER/CER/DER codecs
* Dumps/loads ASN.1 structures from Python types
-* 100% Python, works with Python 2.4 up to Python 3.6
+* 100% Python, works with Python 2.4 up to Python 3.7
* MT-safe
* Contributed ASN.1 compiler [Asn1ate](https://github.com/kimgr/asn1ate)
@@ -180,5 +180,5 @@ post your question [on Stack Overflow](https://stackoverflow.com/questions/ask)
or try browsing pyasn1
[mailing list archives](https://sourceforge.net/p/pyasn1/mailman/pyasn1-users/).
-Copyright (c) 2005-2018, [Ilya Etingof](mailto:etingof@gmail.com).
+Copyright (c) 2005-2019, [Ilya Etingof](mailto:etingof@gmail.com).
All rights reserved.
diff --git a/docs/source/conf.py b/docs/source/conf.py
index ccfbd1c..6ddb378 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -47,7 +47,7 @@ master_doc = 'contents'
# General information about the project.
project = u'ASN.1 types and codecs'
-copyright = u'2005-2018, Ilya Etingof <etingof@gmail.com>'
+copyright = u'2005-2019, Ilya Etingof <etingof@gmail.com>'
author = u'Ilya Etingof <etingof@gmail.com>'
# The version info for the project you're documenting, acts as replacement for
diff --git a/docs/source/example-use-case.rst b/docs/source/example-use-case.rst
index 4efdc81..5e0a7c5 100644
--- a/docs/source/example-use-case.rst
+++ b/docs/source/example-use-case.rst
@@ -45,7 +45,7 @@ tool:
.. code-block:: bash
- $ pyasn1gen.py pkcs-1.asn > rsakey.py
+ $ asn1ate pkcs-1.asn > rsakey.py
Though it may not work out as, as it stands now, asn1ate does not support
all ASN.1 language constructs.
@@ -97,7 +97,7 @@ set on the key file):
from rsakey import RSAPrivateKey
# Read SSH key from file (assuming no passphrase)
- with open open('.ssh/id_rsa') as key_file:
+ with open('.ssh/id_rsa') as key_file:
b64_serialisation = ''.join(key_file.readlines()[1:-1])
# Undo BASE64 serialisation
diff --git a/docs/source/pyasn1/contents.rst b/docs/source/pyasn1/contents.rst
index 102ea87..474bbff 100644
--- a/docs/source/pyasn1/contents.rst
+++ b/docs/source/pyasn1/contents.rst
@@ -20,7 +20,7 @@ implementation of pyasn1 classes from ASN.1 specification.
Both `pyasn1 <https://github.com/etingof/pyasn1>`_ and
`pyasn1-modules <https://github.com/etingof/pyasn1-modules>`_ libraries
-can be used out-of-the-box with Python versions 2.4 through 3.6.
+can be used out-of-the-box with Python versions 2.4 through 3.7.
No external dependencies required.
.. _pyasn1-types:
diff --git a/pyasn1/__init__.py b/pyasn1/__init__.py
index 71bb22f..68db4f1 100644
--- a/pyasn1/__init__.py
+++ b/pyasn1/__init__.py
@@ -1,7 +1,7 @@
import sys
# https://www.python.org/dev/peps/pep-0396/
-__version__ = '0.4.3'
+__version__ = '0.4.5'
if sys.version_info[:2] < (2, 4):
raise RuntimeError('PyASN1 requires Python 2.4 or later')
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py
index a27b3e0..591bbc4 100644
--- a/pyasn1/codec/ber/decoder.py
+++ b/pyasn1/codec/ber/decoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import debug
@@ -18,6 +18,8 @@ from pyasn1.type import useful
__all__ = ['decode']
+LOG = debug.registerLoggee(__name__, flags=debug.DEBUG_DECODER)
+
noValue = base.noValue
@@ -70,6 +72,10 @@ class ExplicitTagDecoder(AbstractSimpleDecoder):
value, _ = decodeFun(head, asn1Spec, tagSet, length, **options)
+ if LOG:
+ LOG('explicit tag container carries %d octets of trailing payload '
+ '(will be lost!): %s' % (len(_), debug.hexdump(_)))
+
return value, tail
def indefLenValueDecoder(self, substrate, asn1Spec,
@@ -120,7 +126,8 @@ class BooleanDecoder(IntegerDecoder):
protoComponent = univ.Boolean(0)
def _createComponent(self, asn1Spec, tagSet, value, **options):
- return IntegerDecoder._createComponent(self, asn1Spec, tagSet, value and 1 or 0, **options)
+ return IntegerDecoder._createComponent(
+ self, asn1Spec, tagSet, value and 1 or 0, **options)
class BitStringDecoder(AbstractSimpleDecoder):
@@ -134,8 +141,8 @@ class BitStringDecoder(AbstractSimpleDecoder):
head, tail = substrate[:length], substrate[length:]
if substrateFun:
- return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options),
- substrate, length)
+ return substrateFun(self._createComponent(
+ asn1Spec, tagSet, noValue, **options), substrate, length)
if not head:
raise error.PyAsn1Error('Empty BIT STRING substrate')
@@ -148,12 +155,17 @@ class BitStringDecoder(AbstractSimpleDecoder):
'Trailing bits overflow %s' % trailingBits
)
- value = self.protoComponent.fromOctetString(head[1:], internalFormat=True, padding=trailingBits)
+ value = self.protoComponent.fromOctetString(
+ head[1:], internalFormat=True, padding=trailingBits)
return self._createComponent(asn1Spec, tagSet, value, **options), tail
if not self.supportConstructedForm:
- raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)
+ raise error.PyAsn1Error('Constructed encoding form prohibited '
+ 'at %s' % self.__class__.__name__)
+
+ if LOG:
+ LOG('assembling constructed serialization')
# All inner fragments are of the same type, treat them as octet string
substrateFun = self.substrateCollector
@@ -234,6 +246,9 @@ class OctetStringDecoder(AbstractSimpleDecoder):
if not self.supportConstructedForm:
raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__)
+ if LOG:
+ LOG('assembling constructed serialization')
+
# All inner fragments are of the same type, treat them as octet string
substrateFun = self.substrateCollector
@@ -267,7 +282,9 @@ class OctetStringDecoder(AbstractSimpleDecoder):
allowEoo=True, **options)
if component is eoo.endOfOctets:
break
+
header += component
+
else:
raise error.SubstrateUnderrunError(
'No EOO seen before substrate ends'
@@ -374,59 +391,90 @@ class RealDecoder(AbstractSimpleDecoder):
if fo & 0x80: # binary encoding
if not head:
raise error.PyAsn1Error("Incomplete floating-point value")
+
+ if LOG:
+ LOG('decoding binary encoded REAL')
+
n = (fo & 0x03) + 1
+
if n == 4:
n = oct2int(head[0])
head = head[1:]
+
eo, head = head[:n], head[n:]
+
if not eo or not head:
raise error.PyAsn1Error('Real exponent screwed')
+
e = oct2int(eo[0]) & 0x80 and -1 or 0
+
while eo: # exponent
e <<= 8
e |= oct2int(eo[0])
eo = eo[1:]
+
b = fo >> 4 & 0x03 # base bits
+
if b > 2:
raise error.PyAsn1Error('Illegal Real base')
+
if b == 1: # encbase = 8
e *= 3
+
elif b == 2: # encbase = 16
e *= 4
p = 0
+
while head: # value
p <<= 8
p |= oct2int(head[0])
head = head[1:]
+
if fo & 0x40: # sign bit
p = -p
+
sf = fo >> 2 & 0x03 # scale bits
p *= 2 ** sf
value = (p, 2, e)
+
elif fo & 0x40: # infinite value
+ if LOG:
+ LOG('decoding infinite REAL')
+
value = fo & 0x01 and '-inf' or 'inf'
+
elif fo & 0xc0 == 0: # character encoding
if not head:
raise error.PyAsn1Error("Incomplete floating-point value")
+
+ if LOG:
+ LOG('decoding character encoded REAL')
+
try:
if fo & 0x3 == 0x1: # NR1
value = (int(head), 10, 0)
+
elif fo & 0x3 == 0x2: # NR2
value = float(head)
+
elif fo & 0x3 == 0x3: # NR3
value = float(head)
+
else:
raise error.SubstrateUnderrunError(
'Unknown NR (tag %s)' % fo
)
+
except ValueError:
raise error.SubstrateUnderrunError(
'Bad character Real syntax'
)
+
else:
raise error.SubstrateUnderrunError(
'Unknown encoding (tag %s)' % fo
)
+
return self._createComponent(asn1Spec, tagSet, value, **options), tail
@@ -447,10 +495,12 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
def _decodeComponents(self, substrate, tagSet=None, decodeFun=None, **options):
components = []
componentTypes = set()
+
while substrate:
component, substrate = decodeFun(substrate, **options)
if component is eoo.endOfOctets:
break
+
components.append(component)
componentTypes.add(component.tagSet)
@@ -460,6 +510,7 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
# * otherwise -> likely SEQUENCE OF/SET OF
if len(componentTypes) > 1:
protoComponent = self.protoRecordComponent
+
else:
protoComponent = self.protoSequenceComponent
@@ -469,6 +520,10 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
tagSet=tag.TagSet(protoComponent.tagSet.baseTag, *tagSet.superTags)
)
+ if LOG:
+ LOG('guessed %r container type (pass `asn1Spec` to guide the '
+ 'decoder)' % asn1Object)
+
for idx, component in enumerate(components):
asn1Object.setComponentByPosition(
idx, component,
@@ -490,8 +545,10 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
if substrateFun is not None:
if asn1Spec is not None:
asn1Object = asn1Spec.clone()
+
elif self.protoComponent is not None:
asn1Object = self.protoComponent.clone(tagSet=tagSet)
+
else:
asn1Object = self.protoRecordComponent, self.protoSequenceComponent
@@ -501,8 +558,12 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
asn1Object, trailing = self._decodeComponents(
head, tagSet=tagSet, decodeFun=decodeFun, **options
)
+
if trailing:
- raise error.PyAsn1Error('Unused trailing %d octets encountered' % len(trailing))
+ if LOG:
+ LOG('Unused trailing %d octets encountered: %s' % (
+ len(trailing), debug.hexdump(trailing)))
+
return asn1Object, tail
asn1Object = asn1Spec.clone()
@@ -514,21 +575,31 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
isSetType = asn1Spec.typeId == univ.Set.typeId
isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault
+ if LOG:
+ LOG('decoding %sdeterministic %s type %r chosen by type ID' % (
+ not isDeterministic and 'non-' or '', isSetType and 'SET' or '',
+ asn1Spec))
+
seenIndices = set()
idx = 0
while head:
if not namedTypes:
componentType = None
+
elif isSetType:
componentType = namedTypes.tagMapUnique
+
else:
try:
if isDeterministic:
componentType = namedTypes[idx].asn1Object
+
elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
componentType = namedTypes.getTagMapNearPosition(idx)
+
else:
componentType = namedTypes[idx].asn1Object
+
except IndexError:
raise error.PyAsn1Error(
'Excessive components decoded at %r' % (asn1Spec,)
@@ -539,6 +610,7 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
if not isDeterministic and namedTypes:
if isSetType:
idx = namedTypes.getPositionByType(component.effectiveTagSet)
+
elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx)
@@ -551,14 +623,22 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
seenIndices.add(idx)
idx += 1
+ if LOG:
+ LOG('seen component indices %s' % seenIndices)
+
if namedTypes:
if not namedTypes.requiredComponents.issubset(seenIndices):
- raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__)
+ raise error.PyAsn1Error(
+ 'ASN.1 object %s has uninitialized '
+ 'components' % asn1Object.__class__.__name__)
if namedTypes.hasOpenTypes:
openTypes = options.get('openTypes', {})
+ if LOG:
+ LOG('using open types map: %r' % openTypes)
+
if openTypes or options.get('decodeOpenTypes', False):
for idx, namedType in enumerate(namedTypes.namedTypes):
@@ -581,8 +661,15 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
openType = namedType.openType[governingValue]
except KeyError:
+ if LOG:
+ LOG('failed to resolve open type by governing '
+ 'value %r' % (governingValue,))
continue
+ if LOG:
+ LOG('resolved open type %r by governing '
+ 'value %r' % (openType, governingValue))
+
component, rest = decodeFun(
asn1Object.getComponentByPosition(idx).asOctets(),
asn1Spec=openType
@@ -598,6 +685,9 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
componentType = asn1Spec.componentType
+ if LOG:
+ LOG('decoding type %r chosen by given `asn1Spec`' % componentType)
+
idx = 0
while head:
@@ -607,6 +697,7 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
verifyConstraints=False,
matchTags=False, matchConstraints=False
)
+
idx += 1
return asn1Object, tail
@@ -621,8 +712,10 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
if substrateFun is not None:
if asn1Spec is not None:
asn1Object = asn1Spec.clone()
+
elif self.protoComponent is not None:
asn1Object = self.protoComponent.clone(tagSet=tagSet)
+
else:
asn1Object = self.protoRecordComponent, self.protoSequenceComponent
@@ -642,21 +735,31 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
isSetType = asn1Object.typeId == univ.Set.typeId
isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault
+ if LOG:
+ LOG('decoding %sdeterministic %s type %r chosen by type ID' % (
+ not isDeterministic and 'non-' or '', isSetType and 'SET' or '',
+ asn1Spec))
+
seenIndices = set()
idx = 0
while substrate:
if len(namedTypes) <= idx:
asn1Spec = None
+
elif isSetType:
asn1Spec = namedTypes.tagMapUnique
+
else:
try:
if isDeterministic:
asn1Spec = namedTypes[idx].asn1Object
+
elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted:
asn1Spec = namedTypes.getTagMapNearPosition(idx)
+
else:
asn1Spec = namedTypes[idx].asn1Object
+
except IndexError:
raise error.PyAsn1Error(
'Excessive components decoded at %r' % (asn1Object,)
@@ -686,13 +789,19 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
'No EOO seen before substrate ends'
)
+ if LOG:
+ LOG('seen component indices %s' % seenIndices)
+
if namedTypes:
if not namedTypes.requiredComponents.issubset(seenIndices):
raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__)
if namedTypes.hasOpenTypes:
- openTypes = options.get('openTypes', None)
+ openTypes = options.get('openTypes', {})
+
+ if LOG:
+ LOG('using open types map: %r' % openTypes)
if openTypes or options.get('decodeOpenTypes', False):
@@ -716,8 +825,15 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
openType = namedType.openType[governingValue]
except KeyError:
+ if LOG:
+ LOG('failed to resolve open type by governing '
+ 'value %r' % (governingValue,))
continue
+ if LOG:
+ LOG('resolved open type %r by governing '
+ 'value %r' % (openType, governingValue))
+
component, rest = decodeFun(
asn1Object.getComponentByPosition(idx).asOctets(),
asn1Spec=openType, allowEoo=True
@@ -734,6 +850,9 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
componentType = asn1Spec.componentType
+ if LOG:
+ LOG('decoding type %r chosen by given `asn1Spec`' % componentType)
+
idx = 0
while substrate:
@@ -747,7 +866,9 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder):
verifyConstraints=False,
matchTags=False, matchConstraints=False
)
+
idx += 1
+
else:
raise error.SubstrateUnderrunError(
'No EOO seen before substrate ends'
@@ -794,18 +915,25 @@ class ChoiceDecoder(AbstractConstructedDecoder):
if asn1Spec is None:
asn1Object = self.protoComponent.clone(tagSet=tagSet)
+
else:
asn1Object = asn1Spec.clone()
if substrateFun:
return substrateFun(asn1Object, substrate, length)
- if asn1Object.tagSet == tagSet: # explicitly tagged Choice
+ if asn1Object.tagSet == tagSet:
+ if LOG:
+ LOG('decoding %s as explicitly tagged CHOICE' % (tagSet,))
+
component, head = decodeFun(
head, asn1Object.componentTagMap, **options
)
else:
+ if LOG:
+ LOG('decoding %s as untagged CHOICE' % (tagSet,))
+
component, head = decodeFun(
head, asn1Object.componentTagMap,
tagSet, length, state, **options
@@ -813,6 +941,9 @@ class ChoiceDecoder(AbstractConstructedDecoder):
effectiveTagSet = component.effectiveTagSet
+ if LOG:
+ LOG('decoded component %s, effective tag set %s' % (component, effectiveTagSet))
+
asn1Object.setComponentByType(
effectiveTagSet, component,
verifyConstraints=False,
@@ -834,18 +965,26 @@ class ChoiceDecoder(AbstractConstructedDecoder):
if substrateFun:
return substrateFun(asn1Object, substrate, length)
- if asn1Object.tagSet == tagSet: # explicitly tagged Choice
+ if asn1Object.tagSet == tagSet:
+ if LOG:
+ LOG('decoding %s as explicitly tagged CHOICE' % (tagSet,))
+
component, substrate = decodeFun(
substrate, asn1Object.componentType.tagMapUnique, **options
)
+
# eat up EOO marker
eooMarker, substrate = decodeFun(
substrate, allowEoo=True, **options
)
+
if eooMarker is not eoo.endOfOctets:
raise error.PyAsn1Error('No EOO seen before substrate ends')
else:
+ if LOG:
+ LOG('decoding %s as untagged CHOICE' % (tagSet,))
+
component, substrate = decodeFun(
substrate, asn1Object.componentType.tagMapUnique,
tagSet, length, state, **options
@@ -853,6 +992,9 @@ class ChoiceDecoder(AbstractConstructedDecoder):
effectiveTagSet = component.effectiveTagSet
+ if LOG:
+ LOG('decoded component %s, effective tag set %s' % (component, effectiveTagSet))
+
asn1Object.setComponentByType(
effectiveTagSet, component,
verifyConstraints=False,
@@ -877,6 +1019,9 @@ class AnyDecoder(AbstractSimpleDecoder):
length += len(fullSubstrate) - len(substrate)
substrate = fullSubstrate
+ if LOG:
+ LOG('decoding as untagged ANY, substrate %s' % debug.hexdump(substrate))
+
if substrateFun:
return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options),
substrate, length)
@@ -892,12 +1037,19 @@ class AnyDecoder(AbstractSimpleDecoder):
if asn1Spec is not None and tagSet == asn1Spec.tagSet:
# tagged Any type -- consume header substrate
header = null
+
+ if LOG:
+ LOG('decoding as tagged ANY')
+
else:
fullSubstrate = options['fullSubstrate']
# untagged Any, recover header substrate
header = fullSubstrate[:-len(substrate)]
+ if LOG:
+ LOG('decoding as untagged ANY, header substrate %s' % debug.hexdump(header))
+
# Any components do not inherit initial tag
asn1Spec = self.protoComponent
@@ -905,6 +1057,9 @@ class AnyDecoder(AbstractSimpleDecoder):
asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options)
return substrateFun(asn1Object, header + substrate, length + len(header))
+ if LOG:
+ LOG('assembling constructed serialization')
+
# All inner fragments are of the same type, treat them as octet string
substrateFun = self.substrateCollector
@@ -914,13 +1069,17 @@ class AnyDecoder(AbstractSimpleDecoder):
allowEoo=True, **options)
if component is eoo.endOfOctets:
break
+
header += component
+
else:
raise error.SubstrateUnderrunError(
'No EOO seen before substrate ends'
)
+
if substrateFun:
return header, substrate
+
else:
return self._createComponent(asn1Spec, tagSet, header, **options), substrate
@@ -1063,21 +1222,16 @@ class Decoder(object):
decodeFun=None, substrateFun=None,
**options):
- if debug.logger & debug.flagDecoder:
- logger = debug.logger
- else:
- logger = None
-
- if logger:
- logger('decoder called at scope %s with state %d, working with up to %d octets of substrate: %s' % (debug.scope, state, len(substrate), debug.hexdump(substrate)))
+ if LOG:
+ LOG('decoder called at scope %s with state %d, working with up to %d octets of substrate: %s' % (debug.scope, state, len(substrate), debug.hexdump(substrate)))
allowEoo = options.pop('allowEoo', False)
# Look for end-of-octets sentinel
if allowEoo and self.supportIndefLength:
if substrate[:2] == self.__eooSentinel:
- if logger:
- logger('end-of-octets sentinel found')
+ if LOG:
+ LOG('end-of-octets sentinel found')
return eoo.endOfOctets, substrate[2:]
value = noValue
@@ -1090,26 +1244,32 @@ class Decoder(object):
fullSubstrate = substrate
while state is not stStop:
+
if state is stDecodeTag:
if not substrate:
raise error.SubstrateUnderrunError(
'Short octet stream on tag decoding'
)
+
# Decode tag
isShortTag = True
firstOctet = substrate[0]
substrate = substrate[1:]
+
try:
lastTag = tagCache[firstOctet]
+
except KeyError:
integerTag = oct2int(firstOctet)
tagClass = integerTag & 0xC0
tagFormat = integerTag & 0x20
tagId = integerTag & 0x1F
+
if tagId == 0x1F:
isShortTag = False
lengthOctetIdx = 0
tagId = 0
+
try:
while True:
integerTag = oct2int(substrate[lengthOctetIdx])
@@ -1118,42 +1278,55 @@ class Decoder(object):
tagId |= (integerTag & 0x7F)
if not integerTag & 0x80:
break
+
substrate = substrate[lengthOctetIdx:]
+
except IndexError:
raise error.SubstrateUnderrunError(
'Short octet stream on long tag decoding'
)
+
lastTag = tag.Tag(
tagClass=tagClass, tagFormat=tagFormat, tagId=tagId
)
+
if isShortTag:
# cache short tags
tagCache[firstOctet] = lastTag
+
if tagSet is None:
if isShortTag:
try:
tagSet = tagSetCache[firstOctet]
+
except KeyError:
# base tag not recovered
tagSet = tag.TagSet((), lastTag)
tagSetCache[firstOctet] = tagSet
else:
tagSet = tag.TagSet((), lastTag)
+
else:
tagSet = lastTag + tagSet
+
state = stDecodeLength
- if logger:
- logger('tag decoded into %s, decoding length' % tagSet)
+
+ if LOG:
+ LOG('tag decoded into %s, decoding length' % tagSet)
+
if state is stDecodeLength:
# Decode length
if not substrate:
raise error.SubstrateUnderrunError(
'Short octet stream on length decoding'
)
+
firstOctet = oct2int(substrate[0])
+
if firstOctet < 128:
size = 1
length = firstOctet
+
elif firstOctet > 128:
size = firstOctet & 0x7F
# encoded in size bytes
@@ -1164,28 +1337,36 @@ class Decoder(object):
raise error.SubstrateUnderrunError(
'%s<%s at %s' % (size, len(encodedLength), tagSet)
)
+
length = 0
for lengthOctet in encodedLength:
length <<= 8
length |= lengthOctet
size += 1
+
else:
size = 1
length = -1
substrate = substrate[size:]
+
if length == -1:
if not self.supportIndefLength:
raise error.PyAsn1Error('Indefinite length encoding not supported by this codec')
+
else:
if len(substrate) < length:
raise error.SubstrateUnderrunError('%d-octet short' % (length - len(substrate)))
+
state = stGetValueDecoder
- if logger:
- logger('value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or substrate[:length])))
+
+ if LOG:
+ LOG('value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or substrate[:length])))
+
if state is stGetValueDecoder:
if asn1Spec is None:
state = stGetValueDecoderByTag
+
else:
state = stGetValueDecoderByAsn1Spec
#
@@ -1207,41 +1388,55 @@ class Decoder(object):
if state is stGetValueDecoderByTag:
try:
concreteDecoder = tagMap[tagSet]
+
except KeyError:
concreteDecoder = None
+
if concreteDecoder:
state = stDecodeValue
+
else:
try:
concreteDecoder = tagMap[tagSet[:1]]
+
except KeyError:
concreteDecoder = None
+
if concreteDecoder:
state = stDecodeValue
else:
state = stTryAsExplicitTag
- if logger:
- logger('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag'))
+
+ if LOG:
+ LOG('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag'))
debug.scope.push(concreteDecoder is None and '?' or concreteDecoder.protoComponent.__class__.__name__)
+
if state is stGetValueDecoderByAsn1Spec:
+
if asn1Spec.__class__ is tagmap.TagMap:
try:
chosenSpec = asn1Spec[tagSet]
+
except KeyError:
chosenSpec = None
- if logger:
- logger('candidate ASN.1 spec is a map of:')
+
+ if LOG:
+ LOG('candidate ASN.1 spec is a map of:')
+
for firstOctet, v in asn1Spec.presentTypes.items():
- logger(' %s -> %s' % (firstOctet, v.__class__.__name__))
+ LOG(' %s -> %s' % (firstOctet, v.__class__.__name__))
+
if asn1Spec.skipTypes:
- logger('but neither of: ')
+ LOG('but neither of: ')
for firstOctet, v in asn1Spec.skipTypes.items():
- logger(' %s -> %s' % (firstOctet, v.__class__.__name__))
- logger('new candidate ASN.1 spec is %s, chosen by %s' % (chosenSpec is None and '<none>' or chosenSpec.prettyPrintType(), tagSet))
+ LOG(' %s -> %s' % (firstOctet, v.__class__.__name__))
+ LOG('new candidate ASN.1 spec is %s, chosen by %s' % (chosenSpec is None and '<none>' or chosenSpec.prettyPrintType(), tagSet))
+
elif tagSet == asn1Spec.tagSet or tagSet in asn1Spec.tagMap:
chosenSpec = asn1Spec
- if logger:
- logger('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__)
+ if LOG:
+ LOG('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__)
+
else:
chosenSpec = None
@@ -1249,29 +1444,38 @@ class Decoder(object):
try:
# ambiguous type or just faster codec lookup
concreteDecoder = typeMap[chosenSpec.typeId]
- if logger:
- logger('value decoder chosen for an ambiguous type by type ID %s' % (chosenSpec.typeId,))
+
+ if LOG:
+ LOG('value decoder chosen for an ambiguous type by type ID %s' % (chosenSpec.typeId,))
+
except KeyError:
# use base type for codec lookup to recover untagged types
baseTagSet = tag.TagSet(chosenSpec.tagSet.baseTag, chosenSpec.tagSet.baseTag)
try:
# base type or tagged subtype
concreteDecoder = tagMap[baseTagSet]
- if logger:
- logger('value decoder chosen by base %s' % (baseTagSet,))
+
+ if LOG:
+ LOG('value decoder chosen by base %s' % (baseTagSet,))
+
except KeyError:
concreteDecoder = None
+
if concreteDecoder:
asn1Spec = chosenSpec
state = stDecodeValue
+
else:
state = stTryAsExplicitTag
+
else:
concreteDecoder = None
state = stTryAsExplicitTag
- if logger:
- logger('codec %s chosen by ASN.1 spec, decoding %s' % (state is stDecodeValue and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag'))
+
+ if LOG:
+ LOG('codec %s chosen by ASN.1 spec, decoding %s' % (state is stDecodeValue and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag'))
debug.scope.push(chosenSpec is None and '?' or chosenSpec.__class__.__name__)
+
if state is stDecodeValue:
if not options.get('recursiveFlag', True) and not substrateFun: # deprecate this
substrateFun = lambda a, b, c: (a, b[:c])
@@ -1285,6 +1489,7 @@ class Decoder(object):
self, substrateFun,
**options
)
+
else:
value, substrate = concreteDecoder.valueDecoder(
substrate, asn1Spec,
@@ -1293,33 +1498,42 @@ class Decoder(object):
**options
)
- if logger:
- logger('codec %s yields type %s, value:\n%s\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, isinstance(value, base.Asn1Item) and value.prettyPrint() or value, substrate and debug.hexdump(substrate) or '<none>'))
+ if LOG:
+ LOG('codec %s yields type %s, value:\n%s\n...remaining substrate is: %s' % (concreteDecoder.__class__.__name__, value.__class__.__name__, isinstance(value, base.Asn1Item) and value.prettyPrint() or value, substrate and debug.hexdump(substrate) or '<none>'))
state = stStop
break
+
if state is stTryAsExplicitTag:
if tagSet and tagSet[0].tagFormat == tag.tagFormatConstructed and tagSet[0].tagClass != tag.tagClassUniversal:
# Assume explicit tagging
concreteDecoder = explicitTagDecoder
state = stDecodeValue
+
else:
concreteDecoder = None
state = self.defaultErrorState
- if logger:
- logger('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as failure'))
+
+ if LOG:
+ LOG('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as failure'))
+
if state is stDumpRawValue:
concreteDecoder = self.defaultRawDecoder
- if logger:
- logger('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__)
+
+ if LOG:
+ LOG('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__)
+
state = stDecodeValue
+
if state is stErrorCondition:
raise error.PyAsn1Error(
'%s not in asn1Spec: %r' % (tagSet, asn1Spec)
)
- if logger:
+
+ if LOG:
debug.scope.pop()
- logger('decoder left scope %s, call completed' % debug.scope)
+ LOG('decoder left scope %s, call completed' % debug.scope)
+
return value, substrate
diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py
index 0094b22..65b8514 100644
--- a/pyasn1/codec/ber/encoder.py
+++ b/pyasn1/codec/ber/encoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import debug
@@ -17,6 +17,8 @@ from pyasn1.type import useful
__all__ = ['encode']
+LOG = debug.registerLoggee(__name__, flags=debug.DEBUG_ENCODER)
+
class AbstractItemEncoder(object):
supportIndefLenMode = True
@@ -31,29 +33,39 @@ class AbstractItemEncoder(object):
encodedTag = tagClass | tagFormat
if isConstructed:
encodedTag |= tag.tagFormatConstructed
+
if tagId < 31:
return encodedTag | tagId,
+
else:
substrate = tagId & 0x7f,
+
tagId >>= 7
+
while tagId:
substrate = (0x80 | (tagId & 0x7f),) + substrate
tagId >>= 7
+
return (encodedTag | 0x1F,) + substrate
def encodeLength(self, length, defMode):
if not defMode and self.supportIndefLenMode:
return (0x80,)
+
if length < 0x80:
return length,
+
else:
substrate = ()
while length:
substrate = (length & 0xff,) + substrate
length >>= 8
+
substrateLen = len(substrate)
+
if substrateLen > 126:
raise error.PyAsn1Error('Length octets overflow (%d)' % substrateLen)
+
return (0x80 | substrateLen,) + substrate
def encodeValue(self, value, asn1Spec, encodeFun, **options):
@@ -85,16 +97,33 @@ class AbstractItemEncoder(object):
value, asn1Spec, encodeFun, **options
)
+ if LOG:
+ LOG('encoded %svalue %s into %s' % (
+ isConstructed and 'constructed ' or '', value, substrate
+ ))
+
if not substrate and isConstructed and options.get('ifNotEmpty', False):
return substrate
- # primitive form implies definite mode
if not isConstructed:
defModeOverride = True
+ if LOG:
+ LOG('overridden encoding mode into definitive for primitive type')
+
header = self.encodeTag(singleTag, isConstructed)
+
+ if LOG:
+ LOG('encoded %stag %s into %s' % (
+ isConstructed and 'constructed ' or '',
+ singleTag, debug.hexdump(ints2octs(header))))
+
header += self.encodeLength(len(substrate), defModeOverride)
+ if LOG:
+ LOG('encoded %s octets (tag + payload) into %s' % (
+ len(substrate), debug.hexdump(ints2octs(header))))
+
if isOctets:
substrate = ints2octs(header) + substrate
@@ -131,6 +160,11 @@ class IntegerEncoder(AbstractItemEncoder):
def encodeValue(self, value, asn1Spec, encodeFun, **options):
if value == 0:
+ if LOG:
+ LOG('encoding %spayload for zero INTEGER' % (
+ self.supportCompactZero and 'no ' or ''
+ ))
+
# de-facto way to encode zero
if self.supportCompactZero:
return (), False, False
@@ -157,11 +191,15 @@ class BitStringEncoder(AbstractItemEncoder):
substrate = alignedValue.asOctets()
return int2oct(len(substrate) * 8 - valueLength) + substrate, False, True
+ if LOG:
+ LOG('encoding into up to %s-octet chunks' % maxChunkSize)
+
baseTag = value.tagSet.baseTag
# strip off explicit tags
if baseTag:
tagSet = tag.TagSet(baseTag, baseTag)
+
else:
tagSet = tag.TagSet()
@@ -195,44 +233,47 @@ class OctetStringEncoder(AbstractItemEncoder):
if not maxChunkSize or len(substrate) <= maxChunkSize:
return substrate, False, True
- else:
+ if LOG:
+ LOG('encoding into up to %s-octet chunks' % maxChunkSize)
- # strip off explicit tags for inner chunks
+ # strip off explicit tags for inner chunks
- if asn1Spec is None:
- baseTag = value.tagSet.baseTag
+ if asn1Spec is None:
+ baseTag = value.tagSet.baseTag
+
+ # strip off explicit tags
+ if baseTag:
+ tagSet = tag.TagSet(baseTag, baseTag)
+
+ else:
+ tagSet = tag.TagSet()
- # strip off explicit tags
- if baseTag:
- tagSet = tag.TagSet(baseTag, baseTag)
- else:
- tagSet = tag.TagSet()
+ asn1Spec = value.clone(tagSet=tagSet)
- asn1Spec = value.clone(tagSet=tagSet)
+ elif not isOctetsType(value):
+ baseTag = asn1Spec.tagSet.baseTag
- elif not isOctetsType(value):
- baseTag = asn1Spec.tagSet.baseTag
+ # strip off explicit tags
+ if baseTag:
+ tagSet = tag.TagSet(baseTag, baseTag)
- # strip off explicit tags
- if baseTag:
- tagSet = tag.TagSet(baseTag, baseTag)
- else:
- tagSet = tag.TagSet()
+ else:
+ tagSet = tag.TagSet()
- asn1Spec = asn1Spec.clone(tagSet=tagSet)
+ asn1Spec = asn1Spec.clone(tagSet=tagSet)
- pos = 0
- substrate = null
+ pos = 0
+ substrate = null
- while True:
- chunk = value[pos:pos + maxChunkSize]
- if not chunk:
- break
+ while True:
+ chunk = value[pos:pos + maxChunkSize]
+ if not chunk:
+ break
- substrate += encodeFun(chunk, asn1Spec, **options)
- pos += maxChunkSize
+ substrate += encodeFun(chunk, asn1Spec, **options)
+ pos += maxChunkSize
- return substrate, True, True
+ return substrate, True, True
class NullEncoder(AbstractItemEncoder):
@@ -268,8 +309,10 @@ class ObjectIdentifierEncoder(AbstractItemEncoder):
oid = (second + 80,) + oid[2:]
else:
raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,))
+
elif first == 2:
oid = (second + 80,) + oid[2:]
+
else:
raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,))
@@ -280,15 +323,19 @@ class ObjectIdentifierEncoder(AbstractItemEncoder):
if 0 <= subOid <= 127:
# Optimize for the common case
octets += (subOid,)
+
elif subOid > 127:
# Pack large Sub-Object IDs
res = (subOid & 0x7f,)
subOid >>= 7
+
while subOid:
res = (0x80 | (subOid & 0x7f),) + res
subOid >>= 7
+
# Add packed Sub-Object ID to resulted Object ID
octets += res
+
else:
raise error.PyAsn1Error('Negative OID arc %s at %s' % (subOid, value))
@@ -304,12 +351,16 @@ class RealEncoder(AbstractItemEncoder):
ms, es = 1, 1
if m < 0:
ms = -1 # mantissa sign
+
if e < 0:
- es = -1 # exponenta sign
+ es = -1 # exponent sign
+
m *= ms
+
if encbase == 8:
m *= 2 ** (abs(e) % 3 * es)
e = abs(e) // 3 * es
+
elif encbase == 16:
m *= 2 ** (abs(e) % 4 * es)
e = abs(e) // 4 * es
@@ -320,6 +371,7 @@ class RealEncoder(AbstractItemEncoder):
e -= 1
continue
break
+
return ms, int(m), encbase, e
def _chooseEncBase(self, value):
@@ -327,23 +379,32 @@ class RealEncoder(AbstractItemEncoder):
encBase = [2, 8, 16]
if value.binEncBase in encBase:
return self._dropFloatingPoint(m, value.binEncBase, e)
+
elif self.binEncBase in encBase:
return self._dropFloatingPoint(m, self.binEncBase, e)
- # auto choosing base 2/8/16
+
+ # auto choosing base 2/8/16
mantissa = [m, m, m]
- exponenta = [e, e, e]
+ exponent = [e, e, e]
sign = 1
encbase = 2
e = float('inf')
+
for i in range(3):
(sign,
mantissa[i],
encBase[i],
- exponenta[i]) = self._dropFloatingPoint(mantissa[i], encBase[i], exponenta[i])
- if abs(exponenta[i]) < abs(e) or (abs(exponenta[i]) == abs(e) and mantissa[i] < m):
- e = exponenta[i]
+ exponent[i]) = self._dropFloatingPoint(mantissa[i], encBase[i], exponent[i])
+
+ if abs(exponent[i]) < abs(e) or (abs(exponent[i]) == abs(e) and mantissa[i] < m):
+ e = exponent[i]
m = int(mantissa[i])
encbase = encBase[i]
+
+ if LOG:
+ LOG('automatically chosen REAL encoding base %s, sign %s, mantissa %s, '
+ 'exponent %s' % (encbase, sign, m, e))
+
return sign, m, encbase, e
def encodeValue(self, value, asn1Spec, encodeFun, **options):
@@ -352,69 +413,98 @@ class RealEncoder(AbstractItemEncoder):
if value.isPlusInf:
return (0x40,), False, False
+
if value.isMinusInf:
return (0x41,), False, False
+
m, b, e = value
+
if not m:
return null, False, True
+
if b == 10:
+ if LOG:
+ LOG('encoding REAL into character form')
+
return str2octs('\x03%dE%s%d' % (m, e == 0 and '+' or '', e)), False, True
+
elif b == 2:
fo = 0x80 # binary encoding
ms, m, encbase, e = self._chooseEncBase(value)
+
if ms < 0: # mantissa sign
fo |= 0x40 # sign bit
- # exponenta & mantissa normalization
+
+ # exponent & mantissa normalization
if encbase == 2:
while m & 0x1 == 0:
m >>= 1
e += 1
+
elif encbase == 8:
while m & 0x7 == 0:
m >>= 3
e += 1
fo |= 0x10
+
else: # encbase = 16
while m & 0xf == 0:
m >>= 4
e += 1
fo |= 0x20
+
sf = 0 # scale factor
+
while m & 0x1 == 0:
m >>= 1
sf += 1
+
if sf > 3:
raise error.PyAsn1Error('Scale factor overflow') # bug if raised
+
fo |= sf << 2
eo = null
if e == 0 or e == -1:
eo = int2oct(e & 0xff)
+
else:
while e not in (0, -1):
eo = int2oct(e & 0xff) + eo
e >>= 8
+
if e == 0 and eo and oct2int(eo[0]) & 0x80:
eo = int2oct(0) + eo
+
if e == -1 and eo and not (oct2int(eo[0]) & 0x80):
eo = int2oct(0xff) + eo
+
n = len(eo)
if n > 0xff:
raise error.PyAsn1Error('Real exponent overflow')
+
if n == 1:
pass
+
elif n == 2:
fo |= 1
+
elif n == 3:
fo |= 2
+
else:
fo |= 3
eo = int2oct(n & 0xff) + eo
+
po = null
+
while m:
po = int2oct(m & 0xff) + po
m >>= 8
+
substrate = int2oct(fo) + eo + po
+
return substrate, False, True
+
else:
raise error.PyAsn1Error('Prohibited Real base %s' % b)
@@ -439,10 +529,14 @@ class SequenceEncoder(AbstractItemEncoder):
namedType = namedTypes[idx]
if namedType.isOptional and not component.isValue:
- continue
+ if LOG:
+ LOG('not encoding OPTIONAL component %r' % (namedType,))
+ continue
if namedType.isDefaulted and component == namedType.asn1Object:
- continue
+ if LOG:
+ LOG('not encoding DEFAULT component %r' % (namedType,))
+ continue
if self.omitEmptyOptionals:
options.update(ifNotEmpty=namedType.isOptional)
@@ -455,6 +549,9 @@ class SequenceEncoder(AbstractItemEncoder):
if wrapType.tagSet and not wrapType.isSameTypeWith(component):
chunk = encodeFun(chunk, wrapType, **options)
+ if LOG:
+ LOG('wrapped open type with wrap type %r' % (wrapType,))
+
substrate += chunk
else:
@@ -465,12 +562,17 @@ class SequenceEncoder(AbstractItemEncoder):
component = value[namedType.name]
except KeyError:
- raise error.PyAsn1Error('Component name "%s" not found in %r' % (namedType.name, value))
+ raise error.PyAsn1Error('Component name "%s" not found in %r' % (
+ namedType.name, value))
if namedType.isOptional and namedType.name not in value:
+ if LOG:
+ LOG('not encoding OPTIONAL component %r' % (namedType,))
continue
if namedType.isDefaulted and component == namedType.asn1Object:
+ if LOG:
+ LOG('not encoding DEFAULT component %r' % (namedType,))
continue
if self.omitEmptyOptionals:
@@ -484,6 +586,9 @@ class SequenceEncoder(AbstractItemEncoder):
if wrapType.tagSet and not wrapType.isSameTypeWith(component):
chunk = encodeFun(chunk, wrapType, **options)
+ if LOG:
+ LOG('wrapped open type with wrap type %r' % (wrapType,))
+
substrate += chunk
return substrate, True, True
@@ -620,13 +725,8 @@ class Encoder(object):
raise error.PyAsn1Error('Value %r is not ASN.1 type instance '
'and "asn1Spec" not given' % (value,))
- if debug.logger & debug.flagEncoder:
- logger = debug.logger
- else:
- logger = None
-
- if logger:
- logger('encoder called in %sdef mode, chunk size %s for '
+ if LOG:
+ LOG('encoder called in %sdef mode, chunk size %s for '
'type %s, value:\n%s' % (not options.get('defMode', True) and 'in' or '', options.get('maxChunkSize', 0), asn1Spec is None and value.prettyPrintType() or asn1Spec.prettyPrintType(), value))
if self.fixedDefLengthMode is not None:
@@ -639,8 +739,8 @@ class Encoder(object):
try:
concreteEncoder = self.__typeMap[typeId]
- if logger:
- logger('using value codec %s chosen by type ID %s' % (concreteEncoder.__class__.__name__, typeId))
+ if LOG:
+ LOG('using value codec %s chosen by type ID %s' % (concreteEncoder.__class__.__name__, typeId))
except KeyError:
if asn1Spec is None:
@@ -657,13 +757,13 @@ class Encoder(object):
except KeyError:
raise error.PyAsn1Error('No encoder for %r (%s)' % (value, tagSet))
- if logger:
- logger('using value codec %s chosen by tagSet %s' % (concreteEncoder.__class__.__name__, tagSet))
+ if LOG:
+ LOG('using value codec %s chosen by tagSet %s' % (concreteEncoder.__class__.__name__, tagSet))
substrate = concreteEncoder.encode(value, asn1Spec, self, **options)
- if logger:
- logger('codec %s built %s octets of substrate: %s\nencoder completed' % (concreteEncoder, len(substrate), debug.hexdump(substrate)))
+ if LOG:
+ LOG('codec %s built %s octets of substrate: %s\nencoder completed' % (concreteEncoder, len(substrate), debug.hexdump(substrate)))
return substrate
diff --git a/pyasn1/codec/ber/eoo.py b/pyasn1/codec/ber/eoo.py
index d4cd827..b613b53 100644
--- a/pyasn1/codec/ber/eoo.py
+++ b/pyasn1/codec/ber/eoo.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1.type import base
diff --git a/pyasn1/codec/cer/decoder.py b/pyasn1/codec/cer/decoder.py
index 66572ec..5099e3c 100644
--- a/pyasn1/codec/cer/decoder.py
+++ b/pyasn1/codec/cer/decoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import error
diff --git a/pyasn1/codec/cer/encoder.py b/pyasn1/codec/cer/encoder.py
index 768d3c1..788567f 100644
--- a/pyasn1/codec/cer/encoder.py
+++ b/pyasn1/codec/cer/encoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import error
@@ -41,7 +41,7 @@ class TimeEncoderMixIn(object):
def encodeValue(self, value, asn1Spec, encodeFun, **options):
# Encoding constraints:
# - minutes are mandatory, seconds are optional
- # - subseconds must NOT be zero
+ # - sub-seconds must NOT be zero
# - no hanging fraction dot
# - time in UTC (Z)
# - only dot is allowed for fractions
diff --git a/pyasn1/codec/der/decoder.py b/pyasn1/codec/der/decoder.py
index f67d025..261bab8 100644
--- a/pyasn1/codec/der/decoder.py
+++ b/pyasn1/codec/der/decoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1.codec.cer import decoder
diff --git a/pyasn1/codec/der/encoder.py b/pyasn1/codec/der/encoder.py
index 756d9fe..5e3c571 100644
--- a/pyasn1/codec/der/encoder.py
+++ b/pyasn1/codec/der/encoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import error
diff --git a/pyasn1/codec/native/decoder.py b/pyasn1/codec/native/decoder.py
index 78fcda6..10e2015 100644
--- a/pyasn1/codec/native/decoder.py
+++ b/pyasn1/codec/native/decoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import debug
@@ -14,6 +14,8 @@ from pyasn1.type import useful
__all__ = ['decode']
+LOG = debug.registerLoggee(__name__, flags=debug.DEBUG_DECODER)
+
class AbstractScalarDecoder(object):
def __call__(self, pyObject, asn1Spec, decodeFun=None, **options):
@@ -136,13 +138,10 @@ class Decoder(object):
self.__typeMap = typeMap
def __call__(self, pyObject, asn1Spec, **options):
- if debug.logger & debug.flagDecoder:
- logger = debug.logger
- else:
- logger = None
- if logger:
+
+ if LOG:
debug.scope.push(type(pyObject).__name__)
- logger('decoder called at scope %s, working with type %s' % (debug.scope, type(pyObject).__name__))
+ LOG('decoder called at scope %s, working with type %s' % (debug.scope, type(pyObject).__name__))
if asn1Spec is None or not isinstance(asn1Spec, base.Asn1Item):
raise error.PyAsn1Error('asn1Spec is not valid (should be an instance of an ASN.1 Item, not %s)' % asn1Spec.__class__.__name__)
@@ -159,13 +158,13 @@ class Decoder(object):
except KeyError:
raise error.PyAsn1Error('Unknown ASN.1 tag %s' % asn1Spec.tagSet)
- if logger:
- logger('calling decoder %s on Python type %s <%s>' % (type(valueDecoder).__name__, type(pyObject).__name__, repr(pyObject)))
+ if LOG:
+ LOG('calling decoder %s on Python type %s <%s>' % (type(valueDecoder).__name__, type(pyObject).__name__, repr(pyObject)))
value = valueDecoder(pyObject, asn1Spec, self, **options)
- if logger:
- logger('decoder %s produced ASN.1 type %s <%s>' % (type(valueDecoder).__name__, type(value).__name__, repr(value)))
+ if LOG:
+ LOG('decoder %s produced ASN.1 type %s <%s>' % (type(valueDecoder).__name__, type(value).__name__, repr(value)))
debug.scope.pop()
return value
diff --git a/pyasn1/codec/native/encoder.py b/pyasn1/codec/native/encoder.py
index 87e50f2..50caa53 100644
--- a/pyasn1/codec/native/encoder.py
+++ b/pyasn1/codec/native/encoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
try:
@@ -20,6 +20,8 @@ from pyasn1.type import useful
__all__ = ['encode']
+LOG = debug.registerLoggee(__name__, flags=debug.DEBUG_ENCODER)
+
class AbstractItemEncoder(object):
def encode(self, value, encodeFun, **options):
@@ -132,14 +134,40 @@ tagMap = {
useful.UTCTime.tagSet: OctetStringEncoder()
}
-# Type-to-codec map for ambiguous ASN.1 types
+
+# Put in ambiguous & non-ambiguous types for faster codec lookup
typeMap = {
+ univ.Boolean.typeId: BooleanEncoder(),
+ univ.Integer.typeId: IntegerEncoder(),
+ univ.BitString.typeId: BitStringEncoder(),
+ univ.OctetString.typeId: OctetStringEncoder(),
+ univ.Null.typeId: NullEncoder(),
+ univ.ObjectIdentifier.typeId: ObjectIdentifierEncoder(),
+ univ.Enumerated.typeId: IntegerEncoder(),
+ univ.Real.typeId: RealEncoder(),
+ # Sequence & Set have same tags as SequenceOf & SetOf
univ.Set.typeId: SetEncoder(),
univ.SetOf.typeId: SequenceOfEncoder(),
univ.Sequence.typeId: SequenceEncoder(),
univ.SequenceOf.typeId: SequenceOfEncoder(),
univ.Choice.typeId: ChoiceEncoder(),
- univ.Any.typeId: AnyEncoder()
+ univ.Any.typeId: AnyEncoder(),
+ # character string types
+ char.UTF8String.typeId: OctetStringEncoder(),
+ char.NumericString.typeId: OctetStringEncoder(),
+ char.PrintableString.typeId: OctetStringEncoder(),
+ char.TeletexString.typeId: OctetStringEncoder(),
+ char.VideotexString.typeId: OctetStringEncoder(),
+ char.IA5String.typeId: OctetStringEncoder(),
+ char.GraphicString.typeId: OctetStringEncoder(),
+ char.VisibleString.typeId: OctetStringEncoder(),
+ char.GeneralString.typeId: OctetStringEncoder(),
+ char.UniversalString.typeId: OctetStringEncoder(),
+ char.BMPString.typeId: OctetStringEncoder(),
+ # useful types
+ useful.ObjectDescriptor.typeId: OctetStringEncoder(),
+ useful.GeneralizedTime.typeId: OctetStringEncoder(),
+ useful.UTCTime.typeId: OctetStringEncoder()
}
@@ -154,14 +182,9 @@ class Encoder(object):
if not isinstance(value, base.Asn1Item):
raise error.PyAsn1Error('value is not valid (should be an instance of an ASN.1 Item)')
- if debug.logger & debug.flagEncoder:
- logger = debug.logger
- else:
- logger = None
-
- if logger:
+ if LOG:
debug.scope.push(type(value).__name__)
- logger('encoder called for type %s <%s>' % (type(value).__name__, value.prettyPrint()))
+ LOG('encoder called for type %s <%s>' % (type(value).__name__, value.prettyPrint()))
tagSet = value.tagSet
@@ -178,13 +201,13 @@ class Encoder(object):
except KeyError:
raise error.PyAsn1Error('No encoder for %s' % (value,))
- if logger:
- logger('using value codec %s chosen by %s' % (concreteEncoder.__class__.__name__, tagSet))
+ if LOG:
+ LOG('using value codec %s chosen by %s' % (concreteEncoder.__class__.__name__, tagSet))
pyObject = concreteEncoder.encode(value, self, **options)
- if logger:
- logger('encoder %s produced: %s' % (type(concreteEncoder).__name__, repr(pyObject)))
+ if LOG:
+ LOG('encoder %s produced: %s' % (type(concreteEncoder).__name__, repr(pyObject)))
debug.scope.pop()
return pyObject
diff --git a/pyasn1/compat/binary.py b/pyasn1/compat/binary.py
index c38a650..addbdc9 100644
--- a/pyasn1/compat/binary.py
+++ b/pyasn1/compat/binary.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from sys import version_info
diff --git a/pyasn1/compat/calling.py b/pyasn1/compat/calling.py
index c60b50d..778a3d1 100644
--- a/pyasn1/compat/calling.py
+++ b/pyasn1/compat/calling.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from sys import version_info
diff --git a/pyasn1/compat/dateandtime.py b/pyasn1/compat/dateandtime.py
index 27526ad..5e471bf 100644
--- a/pyasn1/compat/dateandtime.py
+++ b/pyasn1/compat/dateandtime.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import time
diff --git a/pyasn1/compat/integer.py b/pyasn1/compat/integer.py
index bb3d099..4b31791 100644
--- a/pyasn1/compat/integer.py
+++ b/pyasn1/compat/integer.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/pyasn1/compat/octets.py b/pyasn1/compat/octets.py
index a06db5d..99d23bb 100644
--- a/pyasn1/compat/octets.py
+++ b/pyasn1/compat/octets.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from sys import version_info
diff --git a/pyasn1/compat/string.py b/pyasn1/compat/string.py
index 4d8a045..b9bc8c3 100644
--- a/pyasn1/compat/string.py
+++ b/pyasn1/compat/string.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from sys import version_info
diff --git a/pyasn1/debug.py b/pyasn1/debug.py
index ab72fa8..8707aa8 100644
--- a/pyasn1/debug.py
+++ b/pyasn1/debug.py
@@ -1,10 +1,11 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import logging
+import sys
from pyasn1 import __version__
from pyasn1 import error
@@ -12,18 +13,20 @@ from pyasn1.compat.octets import octs2ints
__all__ = ['Debug', 'setLogger', 'hexdump']
-flagNone = 0x0000
-flagEncoder = 0x0001
-flagDecoder = 0x0002
-flagAll = 0xffff
+DEBUG_NONE = 0x0000
+DEBUG_ENCODER = 0x0001
+DEBUG_DECODER = 0x0002
+DEBUG_ALL = 0xffff
-flagMap = {
- 'none': flagNone,
- 'encoder': flagEncoder,
- 'decoder': flagDecoder,
- 'all': flagAll
+FLAG_MAP = {
+ 'none': DEBUG_NONE,
+ 'encoder': DEBUG_ENCODER,
+ 'decoder': DEBUG_DECODER,
+ 'all': DEBUG_ALL
}
+LOGGEE_MAP = {}
+
class Printer(object):
# noinspection PyShadowingNames
@@ -66,7 +69,7 @@ class Debug(object):
defaultPrinter = Printer()
def __init__(self, *flags, **options):
- self._flags = flagNone
+ self._flags = DEBUG_NONE
if 'loggerName' in options:
# route our logs to parent logger
@@ -89,9 +92,9 @@ class Debug(object):
flag = flag[1:]
try:
if inverse:
- self._flags &= ~flagMap[flag]
+ self._flags &= ~FLAG_MAP[flag]
else:
- self._flags |= flagMap[flag]
+ self._flags |= FLAG_MAP[flag]
except KeyError:
raise error.PyAsn1Error('bad debug flag %s' % flag)
@@ -109,17 +112,26 @@ class Debug(object):
def __rand__(self, flag):
return flag & self._flags
-
-logger = 0
+_LOG = DEBUG_NONE
def setLogger(userLogger):
- global logger
+ global _LOG
if userLogger:
- logger = userLogger
+ _LOG = userLogger
else:
- logger = 0
+ _LOG = DEBUG_NONE
+
+ # Update registered logging clients
+ for module, (name, flags) in LOGGEE_MAP.items():
+ setattr(module, name, _LOG & flags and _LOG or DEBUG_NONE)
+
+
+def registerLoggee(module, name='LOG', flags=DEBUG_NONE):
+ LOGGEE_MAP[sys.modules[module]] = name, flags
+ setLogger(_LOG)
+ return _LOG
def hexdump(octets):
diff --git a/pyasn1/error.py b/pyasn1/error.py
index c05e65c..7f606bb 100644
--- a/pyasn1/error.py
+++ b/pyasn1/error.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
@@ -25,5 +25,5 @@ class SubstrateUnderrunError(PyAsn1Error):
"""Create pyasn1 exception object
The `SubstrateUnderrunError` exception indicates insufficient serialised
- data on input of a deserialisation routine.
+ data on input of a de-serialization routine.
"""
diff --git a/pyasn1/type/base.py b/pyasn1/type/base.py
index adaab22..7995118 100644
--- a/pyasn1/type/base.py
+++ b/pyasn1/type/base.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
@@ -343,10 +343,10 @@ class AbstractSimpleAsn1Item(Asn1ItemBase):
value = self._value
- initilaizers = self.readOnly.copy()
- initilaizers.update(kwargs)
+ initializers = self.readOnly.copy()
+ initializers.update(kwargs)
- return self.__class__(value, **initilaizers)
+ return self.__class__(value, **initializers)
def subtype(self, value=noValue, **kwargs):
"""Create a specialization of |ASN.1| schema or value object.
@@ -540,10 +540,10 @@ class AbstractConstructedAsn1Item(Asn1ItemBase):
"""
cloneValueFlag = kwargs.pop('cloneValueFlag', False)
- initilaizers = self.readOnly.copy()
- initilaizers.update(kwargs)
+ initializers = self.readOnly.copy()
+ initializers.update(kwargs)
- clone = self.__class__(**initilaizers)
+ clone = self.__class__(**initializers)
if cloneValueFlag:
self._cloneComponentValues(clone, cloneValueFlag)
diff --git a/pyasn1/type/char.py b/pyasn1/type/char.py
index 493badb..617b98d 100644
--- a/pyasn1/type/char.py
+++ b/pyasn1/type/char.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/pyasn1/type/constraint.py b/pyasn1/type/constraint.py
index a704331..9d8883d 100644
--- a/pyasn1/type/constraint.py
+++ b/pyasn1/type/constraint.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
# Original concept and code by Mike C. Fletcher.
@@ -352,7 +352,7 @@ class InnerTypeConstraint(AbstractConstraint):
if idx not in self.__multipleTypeConstraint:
raise error.ValueConstraintError(value)
constraint, status = self.__multipleTypeConstraint[idx]
- if status == 'ABSENT': # XXX presense is not checked!
+ if status == 'ABSENT': # XXX presence is not checked!
raise error.ValueConstraintError(value)
constraint(value)
diff --git a/pyasn1/type/error.py b/pyasn1/type/error.py
index b2056bd..80fcf3b 100644
--- a/pyasn1/type/error.py
+++ b/pyasn1/type/error.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1.error import PyAsn1Error
diff --git a/pyasn1/type/namedtype.py b/pyasn1/type/namedtype.py
index f162d19..71f5f11 100644
--- a/pyasn1/type/namedtype.py
+++ b/pyasn1/type/namedtype.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
@@ -265,18 +265,18 @@ class NamedTypes(object):
return nameToPosMap
def __computeAmbiguousTypes(self):
- ambigiousTypes = {}
- partialAmbigiousTypes = ()
+ ambiguousTypes = {}
+ partialAmbiguousTypes = ()
for idx, namedType in reversed(tuple(enumerate(self.__namedTypes))):
if namedType.isOptional or namedType.isDefaulted:
- partialAmbigiousTypes = (namedType,) + partialAmbigiousTypes
+ partialAmbiguousTypes = (namedType,) + partialAmbiguousTypes
else:
- partialAmbigiousTypes = (namedType,)
- if len(partialAmbigiousTypes) == len(self.__namedTypes):
- ambigiousTypes[idx] = self
+ partialAmbiguousTypes = (namedType,)
+ if len(partialAmbiguousTypes) == len(self.__namedTypes):
+ ambiguousTypes[idx] = self
else:
- ambigiousTypes[idx] = NamedTypes(*partialAmbigiousTypes, **dict(terminal=True))
- return ambigiousTypes
+ ambiguousTypes[idx] = NamedTypes(*partialAmbiguousTypes, **dict(terminal=True))
+ return ambiguousTypes
def getTypeByPosition(self, idx):
"""Return ASN.1 type object by its position in fields set.
diff --git a/pyasn1/type/namedval.py b/pyasn1/type/namedval.py
index 59257e4..2233aaf 100644
--- a/pyasn1/type/namedval.py
+++ b/pyasn1/type/namedval.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
# ASN.1 named integers
diff --git a/pyasn1/type/opentype.py b/pyasn1/type/opentype.py
index d14ab34..d37a533 100644
--- a/pyasn1/type/opentype.py
+++ b/pyasn1/type/opentype.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
diff --git a/pyasn1/type/tag.py b/pyasn1/type/tag.py
index 95c226f..b46f491 100644
--- a/pyasn1/type/tag.py
+++ b/pyasn1/type/tag.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import error
diff --git a/pyasn1/type/tagmap.py b/pyasn1/type/tagmap.py
index a9d237f..e53a14d 100644
--- a/pyasn1/type/tagmap.py
+++ b/pyasn1/type/tagmap.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
from pyasn1 import error
diff --git a/pyasn1/type/univ.py b/pyasn1/type/univ.py
index a19f6ba..7fab69f 100644
--- a/pyasn1/type/univ.py
+++ b/pyasn1/type/univ.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import math
@@ -2347,7 +2347,9 @@ class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
if value is noValue:
if componentTypeLen:
- value = componentType.getTypeByPosition(idx).clone()
+ value = componentType.getTypeByPosition(idx)
+ if isinstance(value, base.AbstractConstructedAsn1Item):
+ value = value.clone(cloneValueFlag=componentType[idx].isDefaulted)
elif currentValue is noValue:
raise error.PyAsn1Error('Component type not defined')
@@ -2457,7 +2459,7 @@ class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
scope += 1
representation = self.__class__.__name__ + ':\n'
for idx, componentValue in enumerate(self._componentValues):
- if componentValue is not noValue:
+ if componentValue is not noValue and componentValue.isValue:
representation += ' ' * scope
if self.componentType:
representation += self.componentType.getNameByPosition(idx)
diff --git a/pyasn1/type/useful.py b/pyasn1/type/useful.py
index 146916d..7536b95 100644
--- a/pyasn1/type/useful.py
+++ b/pyasn1/type/useful.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import datetime
diff --git a/setup.py b/setup.py
index cea48b9..fa0a876 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import os
@@ -30,6 +30,7 @@ Programming Language :: Python :: 3.3
Programming Language :: Python :: 3.4
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
+Programming Language :: Python :: 3.7
Topic :: Communications
Topic :: Software Development :: Libraries :: Python Modules
"""
diff --git a/tests/__main__.py b/tests/__main__.py
index 55ccf39..14ef28a 100644
--- a/tests/__main__.py
+++ b/tests/__main__.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
try:
diff --git a/tests/base.py b/tests/base.py
index 645b256..07f06dc 100644
--- a/tests/base.py
+++ b/tests/base.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
diff --git a/tests/codec/__main__.py b/tests/codec/__main__.py
index 8ca201a..7a4cf20 100644
--- a/tests/codec/__main__.py
+++ b/tests/codec/__main__.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
try:
diff --git a/tests/codec/ber/__main__.py b/tests/codec/ber/__main__.py
index aca8493..59c0c2b 100644
--- a/tests/codec/ber/__main__.py
+++ b/tests/codec/ber/__main__.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
try:
diff --git a/tests/codec/ber/test_decoder.py b/tests/codec/ber/test_decoder.py
index d456949..8b6d590 100644
--- a/tests/codec/ber/test_decoder.py
+++ b/tests/codec/ber/test_decoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
@@ -333,7 +333,7 @@ class ObjectIdentifierDecoderTestCase(BaseTestCase):
except PyAsn1Error:
pass
else:
- assert 0, 'Leading 0x80 tolarated'
+ assert 0, 'Leading 0x80 tolerated'
def testLeading0x80Case2(self):
try:
@@ -343,7 +343,7 @@ class ObjectIdentifierDecoderTestCase(BaseTestCase):
except PyAsn1Error:
pass
else:
- assert 0, 'Leading 0x80 tolarated'
+ assert 0, 'Leading 0x80 tolerated'
def testLeading0x80Case3(self):
try:
@@ -353,7 +353,7 @@ class ObjectIdentifierDecoderTestCase(BaseTestCase):
except PyAsn1Error:
pass
else:
- assert 0, 'Leading 0x80 tolarated'
+ assert 0, 'Leading 0x80 tolerated'
def testLeading0x80Case4(self):
try:
@@ -363,7 +363,7 @@ class ObjectIdentifierDecoderTestCase(BaseTestCase):
except PyAsn1Error:
pass
else:
- assert 0, 'Leading 0x80 tolarated'
+ assert 0, 'Leading 0x80 tolerated'
def testTagFormat(self):
try:
@@ -379,7 +379,7 @@ class ObjectIdentifierDecoderTestCase(BaseTestCase):
except PyAsn1Error:
pass
else:
- assert 0, 'zero length tolarated'
+ assert 0, 'zero length tolerated'
def testIndefiniteLength(self):
try:
@@ -429,12 +429,12 @@ class RealDecoderTestCase(BaseTestCase):
ints2octs((9, 3, 160, 254, 1))
) == (univ.Real((1, 2, -8)), null)
- def testBin4(self): # check exponenta = 0
+ def testBin4(self): # check exponent = 0
assert decoder.decode( # (1, 2, 0) encoded with base = 2
ints2octs((9, 3, 128, 0, 1))
) == (univ.Real((1, 2, 0)), null)
- def testBin5(self): # case of 2 octs for exponenta and negative exponenta
+ def testBin5(self): # case of 2 octs for exponent and negative exponent
assert decoder.decode( # (3, 2, -1020) encoded with base = 16
ints2octs((9, 4, 161, 255, 1, 3))
) == (univ.Real((3, 2, -1020)), null)
@@ -1092,7 +1092,7 @@ class SetDecoderWithSchemaTestCase(BaseTestCase):
ints2octs((49, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s
) == (self.s, null)
- def testWithOptionaIndefMode(self):
+ def testWithOptionalIndefMode(self):
self.__initWithOptional()
assert decoder.decode(
ints2octs((49, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 0, 0)), asn1Spec=self.s
diff --git a/tests/codec/ber/test_encoder.py b/tests/codec/ber/test_encoder.py
index 81368a9..26819bd 100644
--- a/tests/codec/ber/test_encoder.py
+++ b/tests/codec/ber/test_encoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
@@ -392,14 +392,14 @@ class RealEncoderTestCase(BaseTestCase):
# choose binEncBase automatically for all further Real (testBin[4-7])
binEncBase, encoder.typeMap[univ.Real.typeId].binEncBase = encoder.typeMap[univ.Real.typeId].binEncBase, None
assert encoder.encode(
- univ.Real((1, 2, 0)) # check exponenta = 0
+ univ.Real((1, 2, 0)) # check exponent = 0
) == ints2octs((9, 3, 128, 0, 1))
encoder.typeMap[univ.Real.typeId].binEncBase = binEncBase
def testBin5(self):
assert encoder.encode(
univ.Real((3, 2, -1020)) # case of 2 octs for exponent and
- # negative exponenta and abs(exponent) is
+ # negative exponent and abs(exponent) is
# all 1's and fills the whole octet(s)
) == ints2octs((9, 4, 129, 252, 4, 3))
diff --git a/tests/codec/cer/__main__.py b/tests/codec/cer/__main__.py
index 043de87..e3643a1 100644
--- a/tests/codec/cer/__main__.py
+++ b/tests/codec/cer/__main__.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
try:
diff --git a/tests/codec/cer/test_decoder.py b/tests/codec/cer/test_decoder.py
index c0aeb78..d4e00ab 100644
--- a/tests/codec/cer/test_decoder.py
+++ b/tests/codec/cer/test_decoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/tests/codec/cer/test_encoder.py b/tests/codec/cer/test_encoder.py
index fd50350..d9d9212 100644
--- a/tests/codec/cer/test_encoder.py
+++ b/tests/codec/cer/test_encoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/tests/codec/der/__main__.py b/tests/codec/der/__main__.py
index b253abb..bfa4ee0 100644
--- a/tests/codec/der/__main__.py
+++ b/tests/codec/der/__main__.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
try:
diff --git a/tests/codec/der/test_decoder.py b/tests/codec/der/test_decoder.py
index 554e2e6..a76c435 100644
--- a/tests/codec/der/test_decoder.py
+++ b/tests/codec/der/test_decoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/tests/codec/der/test_encoder.py b/tests/codec/der/test_encoder.py
index 4c58df2..75835f2 100644
--- a/tests/codec/der/test_encoder.py
+++ b/tests/codec/der/test_encoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/tests/codec/native/__main__.py b/tests/codec/native/__main__.py
index efd4303..640f586 100644
--- a/tests/codec/native/__main__.py
+++ b/tests/codec/native/__main__.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
try:
diff --git a/tests/codec/native/test_decoder.py b/tests/codec/native/test_decoder.py
index 7bdfff8..654e2cc 100644
--- a/tests/codec/native/test_decoder.py
+++ b/tests/codec/native/test_decoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/tests/codec/native/test_encoder.py b/tests/codec/native/test_encoder.py
index 8c35b55..25c9979 100644
--- a/tests/codec/native/test_encoder.py
+++ b/tests/codec/native/test_encoder.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/tests/compat/__main__.py b/tests/compat/__main__.py
index 225ad90..296d70c 100644
--- a/tests/compat/__main__.py
+++ b/tests/compat/__main__.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
try:
diff --git a/tests/compat/test_binary.py b/tests/compat/test_binary.py
index 4fa1d64..3e0949f 100644
--- a/tests/compat/test_binary.py
+++ b/tests/compat/test_binary.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/tests/compat/test_integer.py b/tests/compat/test_integer.py
index 3f16f7a..04fd86a 100644
--- a/tests/compat/test_integer.py
+++ b/tests/compat/test_integer.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/tests/compat/test_octets.py b/tests/compat/test_octets.py
index e552526..5a9bc7c 100644
--- a/tests/compat/test_octets.py
+++ b/tests/compat/test_octets.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/tests/test_debug.py b/tests/test_debug.py
index 94a867e..9e33f93 100644
--- a/tests/test_debug.py
+++ b/tests/test_debug.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/tests/type/__main__.py b/tests/type/__main__.py
index b88bff9..fcc66e7 100644
--- a/tests/type/__main__.py
+++ b/tests/type/__main__.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
try:
diff --git a/tests/type/test_char.py b/tests/type/test_char.py
index abae715..8540a3e 100644
--- a/tests/type/test_char.py
+++ b/tests/type/test_char.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import pickle
diff --git a/tests/type/test_constraint.py b/tests/type/test_constraint.py
index 2cdc66e..b5276cd 100644
--- a/tests/type/test_constraint.py
+++ b/tests/type/test_constraint.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
@@ -25,7 +25,7 @@ class SingleValueConstraintTestCase(BaseTestCase):
self.c2 = constraint.SingleValueConstraint(3, 4)
def testCmp(self):
- assert self.c1 == self.c1, 'comparation fails'
+ assert self.c1 == self.c1, 'comparison fails'
def testHash(self):
assert hash(self.c1) != hash(self.c2), 'hash() fails'
@@ -195,7 +195,6 @@ class InnerTypeConstraintTestCase(BaseTestCase):
try:
c(4, 0)
except error.ValueConstraintError:
- raise
assert 0, 'constraint check fails'
try:
c(4, 1)
diff --git a/tests/type/test_namedtype.py b/tests/type/test_namedtype.py
index e8fda88..7cff45e 100644
--- a/tests/type/test_namedtype.py
+++ b/tests/type/test_namedtype.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/tests/type/test_namedval.py b/tests/type/test_namedval.py
index 0911d43..4ac08cf 100644
--- a/tests/type/test_namedval.py
+++ b/tests/type/test_namedval.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/tests/type/test_opentype.py b/tests/type/test_opentype.py
index 46b5c10..ff6788f 100644
--- a/tests/type/test_opentype.py
+++ b/tests/type/test_opentype.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
diff --git a/tests/type/test_tag.py b/tests/type/test_tag.py
index e0cf483..e8dd7a3 100644
--- a/tests/type/test_tag.py
+++ b/tests/type/test_tag.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import sys
@@ -31,10 +31,10 @@ class TagReprTestCase(TagTestCaseBase):
class TagCmpTestCase(TagTestCaseBase):
def testCmp(self):
- assert self.t1 == self.t2, 'tag comparation fails'
+ assert self.t1 == self.t2, 'tag comparison fails'
def testHash(self):
- assert hash(self.t1) == hash(self.t2), 'tag hash comparation fails'
+ assert hash(self.t1) == hash(self.t2), 'tag hash comparison fails'
def testSequence(self):
assert self.t1[0] == self.t2[0] and \
@@ -62,13 +62,13 @@ class TagSetReprTestCase(TagSetTestCaseBase):
class TagSetCmpTestCase(TagSetTestCaseBase):
def testCmp(self):
- assert self.ts1 == self.ts2, 'tag set comparation fails'
+ assert self.ts1 == self.ts2, 'tag set comparison fails'
def testHash(self):
assert hash(self.ts1) == hash(self.ts2), 'tag set hash comp. fails'
def testLen(self):
- assert len(self.ts1) == len(self.ts2), 'tag length comparation fails'
+ assert len(self.ts1) == len(self.ts2), 'tag length comparison fails'
class TaggingTestSuite(TagSetTestCaseBase):
diff --git a/tests/type/test_univ.py b/tests/type/test_univ.py
index ab44f3a..a44f82a 100644
--- a/tests/type/test_univ.py
+++ b/tests/type/test_univ.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import math
@@ -1065,7 +1065,7 @@ class SequenceOf(BaseTestCase):
else:
assert False, 'IndexError not raised'
- # this is a deviation from standart sequence protocol
+ # this is a deviation from standard sequence protocol
assert not s[1]
def testSetItem(self):
@@ -1407,6 +1407,22 @@ class Sequence(BaseTestCase):
s.clear()
assert s.getComponentByPosition(1, default=None) is None
+ def testGetComponentWithConstructedDefault(self):
+
+ class Sequence(univ.Sequence):
+ componentType = namedtype.NamedTypes(
+ namedtype.NamedType('name', univ.OctetString()),
+ namedtype.DefaultedNamedType('nick', univ.SequenceOf(
+ componentType=univ.Integer()
+ ).setComponentByPosition(0, 1)),
+ )
+
+ s = Sequence()
+
+ assert s.getComponentByPosition(1, default=None, instantiate=False) is None
+ assert s.getComponentByPosition(1, instantiate=False) is univ.noValue
+ assert s.getComponentByPosition(1) == [1]
+
def testGetComponentNoInstantiation(self):
class Sequence(univ.Sequence):
diff --git a/tests/type/test_useful.py b/tests/type/test_useful.py
index c1d7832..8a5ab30 100644
--- a/tests/type/test_useful.py
+++ b/tests/type/test_useful.py
@@ -1,7 +1,7 @@
#
# This file is part of pyasn1 software.
#
-# Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
+# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
import datetime