summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.rst2
-rw-r--r--pyasn1/codec/cer/encoder.py2
-rw-r--r--pyasn1/codec/der/encoder.py3
-rw-r--r--tests/codec/cer/test_encoder.py45
-rw-r--r--tests/codec/der/test_encoder.py48
5 files changed, 95 insertions, 5 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index a52d87a..163db23 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -17,6 +17,8 @@ Revision 0.4.1, released XX-10-2017
- Fixed ASN.1 encoder not to omit empty substrate produced for inner
component if the inner component belongs to the simple class (as
opposed to constructed class).
+- Fixed CER/DER encoders to respect tagged CHOICE when ordering
+ SET components
Revision 0.3.7, released 04-10-2017
-----------------------------------
diff --git a/pyasn1/codec/cer/encoder.py b/pyasn1/codec/cer/encoder.py
index 7dc14ac..52216fe 100644
--- a/pyasn1/codec/cer/encoder.py
+++ b/pyasn1/codec/cer/encoder.py
@@ -92,7 +92,7 @@ class SetEncoder(encoder.SequenceEncoder):
if asn1Spec is None:
asn1Spec = component
- if asn1Spec.typeId == univ.Choice.typeId:
+ if asn1Spec.typeId == univ.Choice.typeId and not asn1Spec.tagSet:
if asn1Spec.tagSet:
return asn1Spec.tagSet
else:
diff --git a/pyasn1/codec/der/encoder.py b/pyasn1/codec/der/encoder.py
index e410531..14ae2c9 100644
--- a/pyasn1/codec/der/encoder.py
+++ b/pyasn1/codec/der/encoder.py
@@ -25,7 +25,7 @@ class SetEncoder(encoder.SetEncoder):
else:
compType = asn1Spec
- if compType.typeId == univ.Choice.typeId:
+ if compType.typeId == univ.Choice.typeId and not compType.tagSet:
if asn1Spec is None:
return component.getComponent().tagSet
else:
@@ -36,6 +36,7 @@ class SetEncoder(encoder.SetEncoder):
raise error.PyAsn1Error(
'%s components for Choice at %r' % (len(names) and 'Multiple ' or 'None ', component))
+ # TODO: support nested CHOICE ordering
return asn1Spec[names[0]].tagSet
else:
diff --git a/tests/codec/cer/test_encoder.py b/tests/codec/cer/test_encoder.py
index 32d87b0..a100157 100644
--- a/tests/codec/cer/test_encoder.py
+++ b/tests/codec/cer/test_encoder.py
@@ -13,7 +13,7 @@ except ImportError:
from tests.base import BaseTestCase
-from pyasn1.type import namedtype, univ, useful
+from pyasn1.type import tag, namedtype, univ, useful
from pyasn1.codec.cer import encoder
from pyasn1.compat.octets import ints2octs
from pyasn1.error import PyAsn1Error
@@ -378,6 +378,49 @@ class SetWithChoiceWithSchemaEncoderTestCase(BaseTestCase):
assert encoder.encode(self.s) == ints2octs((49, 128, 1, 1, 255, 5, 0, 0, 0))
+class SetWithTaggedChoiceEncoderTestCase(BaseTestCase):
+
+ def testWithUntaggedChoice(self):
+
+ c = univ.Choice(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('premium', univ.Boolean())
+ )
+ )
+
+ s = univ.Set(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('name', univ.OctetString()),
+ namedtype.NamedType('customer', c)
+ )
+ )
+
+ s.setComponentByName('name', 'A')
+ s.getComponentByName('customer').setComponentByName('premium', True)
+
+ assert encoder.encode(s) == ints2octs((49, 128, 1, 1, 255, 4, 1, 65, 0, 0))
+
+ def testWithTaggedChoice(self):
+
+ c = univ.Choice(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('premium', univ.Boolean())
+ )
+ ).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 7))
+
+ s = univ.Set(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('name', univ.OctetString()),
+ namedtype.NamedType('customer', c)
+ )
+ )
+
+ s.setComponentByName('name', 'A')
+ s.getComponentByName('customer').setComponentByName('premium', True)
+
+ assert encoder.encode(s) == ints2octs((49, 128, 4, 1, 65, 167, 128, 1, 1, 255, 0, 0, 0, 0))
+
+
class SetEncoderTestCase(BaseTestCase):
def setUp(self):
BaseTestCase.setUp(self)
diff --git a/tests/codec/der/test_encoder.py b/tests/codec/der/test_encoder.py
index 66a8a91..e06c769 100644
--- a/tests/codec/der/test_encoder.py
+++ b/tests/codec/der/test_encoder.py
@@ -13,7 +13,7 @@ except ImportError:
from tests.base import BaseTestCase
-from pyasn1.type import namedtype, univ
+from pyasn1.type import tag, namedtype, univ
from pyasn1.codec.der import encoder
from pyasn1.compat.octets import ints2octs
@@ -76,7 +76,8 @@ class SetOfEncoderTestCase(BaseTestCase):
assert encoder.encode(self.s) == ints2octs((49, 6, 4, 1, 97, 4, 1, 98))
-class SetWithChoiceEncoderTestCase(BaseTestCase):
+
+class SetWithAlternatingChoiceEncoderTestCase(BaseTestCase):
def setUp(self):
BaseTestCase.setUp(self)
@@ -101,6 +102,49 @@ class SetWithChoiceEncoderTestCase(BaseTestCase):
assert encoder.encode(self.s) == ints2octs((49, 6, 1, 1, 255, 2, 1, 5))
+class SetWithTaggedChoiceEncoderTestCase(BaseTestCase):
+
+ def testWithUntaggedChoice(self):
+
+ c = univ.Choice(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('premium', univ.Boolean())
+ )
+ )
+
+ s = univ.Set(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('name', univ.OctetString()),
+ namedtype.NamedType('customer', c)
+ )
+ )
+
+ s.setComponentByName('name', 'A')
+ s.getComponentByName('customer').setComponentByName('premium', True)
+
+ assert encoder.encode(s) == ints2octs((49, 6, 1, 1, 255, 4, 1, 65))
+
+ def testWithTaggedChoice(self):
+
+ c = univ.Choice(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('premium', univ.Boolean())
+ )
+ ).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 7))
+
+ s = univ.Set(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('name', univ.OctetString()),
+ namedtype.NamedType('customer', c)
+ )
+ )
+
+ s.setComponentByName('name', 'A')
+ s.getComponentByName('customer').setComponentByName('premium', True)
+
+ assert encoder.encode(s) == ints2octs((49, 8, 4, 1, 65, 167, 3, 1, 1, 255))
+
+
class NestedOptionalSequenceEncoderTestCase(BaseTestCase):
def setUp(self):
BaseTestCase.setUp(self)