summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Etingof <etingof@gmail.com>2017-09-20 22:18:12 +0200
committerGitHub <noreply@github.com>2017-09-20 22:18:12 +0200
commit8b62fa2618ee3dbd193c40671d492bf4ea95d8e1 (patch)
tree84c0366f130a3afc8fde4db0a675dacd28c2e6d8
parentaaf2ad1f54a3d9b44f2bd800653a4f62deeee50c (diff)
downloadpyasn1-git-8b62fa2618ee3dbd193c40671d492bf4ea95d8e1.tar.gz
fixed crash on exp tagged Sequence component encoding (#79)
Also EOO encoder call replaced with a constant outcome
-rw-r--r--CHANGES.rst3
-rw-r--r--pyasn1/codec/ber/encoder.py18
-rw-r--r--tests/codec/ber/test_encoder.py20
3 files changed, 38 insertions, 3 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 724771d..5ee2c15 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -2,8 +2,11 @@
Revision 0.3.6, released XX-09-2017
-----------------------------------
+- End-of-octets encoding optimized at ASN.1 encoders
- The __getitem__/__setitem__ behavior of Set/Sequence and SetOf/SequenceOf
objects aligned with the canonical Mapping and Sequence protocols in part
+- Fixed crash in ASN.1 encoder when encoding an explicitly tagged
+ component of a Sequence
Revision 0.3.5, released 16-09-2017
-----------------------------------
diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py
index 3ac2ef8..4ed4c3b 100644
--- a/pyasn1/codec/ber/encoder.py
+++ b/pyasn1/codec/ber/encoder.py
@@ -16,6 +16,10 @@ __all__ = ['encode']
class AbstractItemEncoder(object):
supportIndefLenMode = 1
+ # An outcome of otherwise legit call `encodeFun(eoo.endOfOctets)`
+ eooIntegerSubstrate = (0, 0)
+ eooOctetsSubstrate = ints2octs(eooIntegerSubstrate)
+
# noinspection PyMethodMayBeStatic
def encodeTag(self, singleTag, isConstructed):
tagClass, tagFormat, tagId = singleTag
@@ -85,11 +89,18 @@ class AbstractItemEncoder(object):
if isOctets:
substrate = ints2octs(header) + substrate
+
+ if not defModeOverride:
+ substrate += self.eooOctetsSubstrate
+
else:
- substrate = ints2octs(header + substrate)
+ substrate = header + substrate
- if not defModeOverride:
- substrate += encodeFun(eoo.endOfOctets, defMode=defModeOverride)
+ if not defModeOverride:
+ substrate += self.eooIntegerSubstrate
+
+ if not isOctets:
+ substrate = ints2octs(substrate)
return substrate
@@ -506,6 +517,7 @@ class Encoder(object):
if logger:
logger('codec %s built %s octets of substrate: %s\nencoder completed' % (concreteEncoder, len(substrate), debug.hexdump(substrate)))
+
return substrate
#: Turns ASN.1 object into BER octet stream.
diff --git a/tests/codec/ber/test_encoder.py b/tests/codec/ber/test_encoder.py
index 265e866..09a7572 100644
--- a/tests/codec/ber/test_encoder.py
+++ b/tests/codec/ber/test_encoder.py
@@ -655,6 +655,26 @@ class ExpTaggedSequenceEncoderTestCase(BaseTestCase):
) == ints2octs((101, 128, 48, 128, 2, 1, 12, 0, 0, 0, 0))
+class ExpTaggedSequenceComponentEncoderTestCase(BaseTestCase):
+ def setUp(self):
+ BaseTestCase.setUp(self)
+ self.s = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('number', univ.Boolean().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))),
+ )
+ )
+
+ self.s[0] = True
+
+ def testDefMode(self):
+ assert encoder.encode(self.s) == ints2octs((48, 5, 160, 3, 1, 1, 1))
+
+ def testIndefMode(self):
+ assert encoder.encode(
+ self.s, defMode=False
+ ) == ints2octs((48, 128, 160, 3, 1, 1, 1, 0, 0, 0, 0))
+
+
class SetEncoderTestCase(BaseTestCase):
def setUp(self):
BaseTestCase.setUp(self)