diff options
author | Ilya Etingof <etingof@gmail.com> | 2017-09-14 19:52:52 +0200 |
---|---|---|
committer | Ilya Etingof <etingof@gmail.com> | 2017-09-14 19:52:52 +0200 |
commit | cebfcb2d328ee42151ac8822b135613aa025fc54 (patch) | |
tree | e493199e54968e4281ff2a669cf9ea424723256d | |
parent | c40b8c22c9679e017871617d7cf558b1b7f0ff84 (diff) | |
parent | 154c55b30e335482a074ac76ad4e5abdc41ccc8b (diff) | |
download | pyasn1-cebfcb2d328ee42151ac8822b135613aa025fc54.tar.gz |
Merge branch 'master' into open-types-support
-rw-r--r-- | CHANGES.rst | 3 | ||||
-rw-r--r-- | pyasn1/codec/ber/encoder.py | 11 | ||||
-rw-r--r-- | pyasn1/codec/cer/encoder.py | 30 | ||||
-rw-r--r-- | pyasn1/codec/der/encoder.py | 24 | ||||
-rw-r--r-- | tests/codec/der/test_encoder.py | 23 |
5 files changed, 26 insertions, 65 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index 72f7526..cb252ec 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -10,6 +10,9 @@ Revision 0.3.5, released XX-09-2017 - Codecs signatures unified and pass **options through the call chain - Explicit tag encoding optimized to avoid unnecessary copying - End-of-octets sentinel encoding optimized +- Refactored ASN.1 codecs properties to silently enforce proper length and + chunk size encoding modes +- Fixed DER encoder to always produce primitive encoding Revision 0.3.4, released 07-09-2017 ----------------------------------- diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py index 0d48a90..c970726 100644 --- a/pyasn1/codec/ber/encoder.py +++ b/pyasn1/codec/ber/encoder.py @@ -470,7 +470,8 @@ typeMap = { class Encoder(object): - supportIndefLength = True + fixedDefLengthMode = None + fixedChunkSize = None # noinspection PyDefaultArgument def __init__(self, tagMap, typeMap={}): @@ -478,8 +479,6 @@ class Encoder(object): self.__typeMap = typeMap def __call__(self, value, **options): - if not options.get('defMode', True) and not self.supportIndefLength: - raise error.PyAsn1Error('Indefinite length encoding not supported by this codec') if debug.logger & debug.flagEncoder: logger = debug.logger @@ -489,6 +488,12 @@ class Encoder(object): if logger: logger('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), value.prettyPrintType(), value.prettyPrint())) + if self.fixedDefLengthMode is not None: + options.update(defMode=self.fixedDefLengthMode) + + if self.fixedChunkSize is not None: + options.update(maxChunkSize=self.fixedChunkSize) + tagSet = value.tagSet try: diff --git a/pyasn1/codec/cer/encoder.py b/pyasn1/codec/cer/encoder.py index e305a6d..40e7eba 100644 --- a/pyasn1/codec/cer/encoder.py +++ b/pyasn1/codec/cer/encoder.py @@ -22,22 +22,6 @@ class BooleanEncoder(encoder.IntegerEncoder): return substrate, False, False -class BitStringEncoder(encoder.BitStringEncoder): - def encodeValue(self, value, encodeFun, **options): - options.update(maxChunkSize=1000) - return encoder.BitStringEncoder.encodeValue( - self, value, encodeFun, **options - ) - - -class OctetStringEncoder(encoder.OctetStringEncoder): - def encodeValue(self, value, encodeFun, **options): - options.update(maxChunkSize=1000) - return encoder.OctetStringEncoder.encodeValue( - self, value, encodeFun, **options - ) - - class RealEncoder(encoder.RealEncoder): def _chooseEncBase(self, value): m, b, e = value @@ -83,7 +67,7 @@ class TimeEncoderMixIn(object): ) -class GeneralizedTimeEncoder(TimeEncoderMixIn, OctetStringEncoder): +class GeneralizedTimeEncoder(TimeEncoderMixIn, encoder.OctetStringEncoder): minLength = 12 maxLength = 19 @@ -190,8 +174,6 @@ class SequenceOfEncoder(encoder.SequenceOfEncoder): tagMap = encoder.tagMap.copy() tagMap.update({ univ.Boolean.tagSet: BooleanEncoder(), - univ.BitString.tagSet: BitStringEncoder(), - univ.OctetString.tagSet: OctetStringEncoder(), univ.Real.tagSet: RealEncoder(), useful.GeneralizedTime.tagSet: GeneralizedTimeEncoder(), useful.UTCTime.tagSet: UTCTimeEncoder(), @@ -203,8 +185,6 @@ tagMap.update({ typeMap = encoder.typeMap.copy() typeMap.update({ univ.Boolean.typeId: BooleanEncoder(), - univ.BitString.typeId: BitStringEncoder(), - univ.OctetString.typeId: OctetStringEncoder(), univ.Real.typeId: RealEncoder(), useful.GeneralizedTime.typeId: GeneralizedTimeEncoder(), useful.UTCTime.typeId: UTCTimeEncoder(), @@ -217,12 +197,8 @@ typeMap.update({ class Encoder(encoder.Encoder): - supportIndefLength = True - - def __call__(self, value, **options): - if 'defMode' not in options: - options.update(defMode=False) - return encoder.Encoder.__call__(self, value, **options) + fixedDefLengthMode = False + fixedChunkSize = 1000 #: Turns ASN.1 object into CER octet stream. #: diff --git a/pyasn1/codec/der/encoder.py b/pyasn1/codec/der/encoder.py index 59dd512..d2992a9 100644 --- a/pyasn1/codec/der/encoder.py +++ b/pyasn1/codec/der/encoder.py @@ -10,18 +10,6 @@ from pyasn1.codec.cer import encoder __all__ = ['encode'] -class BitStringEncoder(encoder.BitStringEncoder): - def encodeValue(self, value, encodeFun, **options): - return encoder.BitStringEncoder.encodeValue( - self, value, encodeFun, **options - ) - -class OctetStringEncoder(encoder.OctetStringEncoder): - def encodeValue(self, value, encodeFun, **options): - return encoder.OctetStringEncoder.encodeValue( - self, value, encodeFun, **options - ) - class SetOfEncoder(encoder.SetOfEncoder): @staticmethod def _sortComponents(components): @@ -30,16 +18,12 @@ class SetOfEncoder(encoder.SetOfEncoder): tagMap = encoder.tagMap.copy() tagMap.update({ - univ.BitString.tagSet: BitStringEncoder(), - univ.OctetString.tagSet: OctetStringEncoder(), # Set & SetOf have same tags univ.SetOf.tagSet: SetOfEncoder() }) typeMap = encoder.typeMap.copy() typeMap.update({ - univ.BitString.typeId: BitStringEncoder(), - univ.OctetString.typeId: OctetStringEncoder(), # Set & SetOf have same tags univ.Set.typeId: SetOfEncoder(), univ.SetOf.typeId: SetOfEncoder() @@ -47,12 +31,8 @@ typeMap.update({ class Encoder(encoder.Encoder): - supportIndefLength = False - - def __call__(self, value, **options): - if 'defMode' not in options: - options.update(defMode=True) - return encoder.Encoder.__call__(self, value, **options) + fixedDefLengthMode = True + fixedChunkSize = 0 #: Turns ASN.1 object into DER octet stream. #: diff --git a/tests/codec/der/test_encoder.py b/tests/codec/der/test_encoder.py index d30dfc1..354781a 100644 --- a/tests/codec/der/test_encoder.py +++ b/tests/codec/der/test_encoder.py @@ -17,31 +17,28 @@ from pyasn1.error import PyAsn1Error class OctetStringEncoderTestCase(unittest.TestCase): - def testShortMode(self): + def testDefModeShort(self): assert encoder.encode( univ.OctetString('Quick brown fox') ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) - def testIndefMode(self): - try: - encoder.encode(univ.OctetString('Quick brown'), defMode=False) - except PyAsn1Error: - pass - else: - assert 0, 'Indefinite length encoding tolerated' - - def testChunkedMode(self): + def testDefModeLong(self): assert encoder.encode( - univ.OctetString('Quick brown'), maxChunkSize=2 - ) == ints2octs((4, 11, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)) + univ.OctetString('Q' * 10000) + ) == ints2octs((4, 130, 39, 16) + (81,) * 10000) class BitStringEncoderTestCase(unittest.TestCase): - def testShortMode(self): + def testDefModeShort(self): assert encoder.encode( univ.BitString((1,)) ) == ints2octs((3, 2, 7, 128)) + def testDefModeLong(self): + assert encoder.encode( + univ.BitString((1,) * 80000) + ) == ints2octs((3, 130, 39, 17, 0) + (255,) * 10000) + class SetOfEncoderTestCase(unittest.TestCase): def setUp(self): |