From adf4c5b1ef11026102dad0bb77b54576e0ebd71c Mon Sep 17 00:00:00 2001 From: Ilya Etingof Date: Fri, 28 Jun 2019 22:48:40 +0200 Subject: Fix `AnyDecoder` to accept `TagMap` as `asn1Spec` (#152) Fixes `AnyDecoder` to accept `TagMap` as `asn1Spec`. The use-case is to make `AnyDecoder` operational when dumping raw value on error condition is enabled --- CHANGES.rst | 2 ++ pyasn1/codec/ber/decoder.py | 28 ++++++++++++++++++++++++---- tests/codec/ber/test_decoder.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 19e7bd9..1bcd5f6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -26,6 +26,8 @@ Revision 0.4.6, released XX-06-2019 becomes a value object. - Added `.reset()` method to all constructed types to turn value object into a schema object. +- Fixed `AnyDecoder` to accept possible `TagMap` as `asn1Spec` + to make dumping raw value operational Revision 0.4.5, released 29-12-2018 ----------------------------------- diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py index 2e4afbb..8c556fc 100644 --- a/pyasn1/codec/ber/decoder.py +++ b/pyasn1/codec/ber/decoder.py @@ -1016,7 +1016,16 @@ class AnyDecoder(AbstractSimpleDecoder): tagSet=None, length=None, state=None, decodeFun=None, substrateFun=None, **options): - if asn1Spec is None or asn1Spec is not None and tagSet != asn1Spec.tagSet: + if asn1Spec is None: + isUntagged = True + + elif asn1Spec.__class__ is tagmap.TagMap: + isUntagged = tagSet not in asn1Spec.tagMap + + else: + isUntagged = tagSet != asn1Spec.tagSet + + if isUntagged: fullSubstrate = options['fullSubstrate'] # untagged Any container, recover inner header substrate @@ -1038,7 +1047,16 @@ class AnyDecoder(AbstractSimpleDecoder): tagSet=None, length=None, state=None, decodeFun=None, substrateFun=None, **options): - if asn1Spec is not None and tagSet == asn1Spec.tagSet: + if asn1Spec is None: + isTagged = False + + elif asn1Spec.__class__ is tagmap.TagMap: + isTagged = tagSet in asn1Spec.tagMap + + else: + isTagged = tagSet == asn1Spec.tagSet + + if isTagged: # tagged Any type -- consume header substrate header = null @@ -1208,7 +1226,7 @@ for typeDecoder in tagMap.values(): class Decoder(object): defaultErrorState = stErrorCondition - # defaultErrorState = stDumpRawValue + #defaultErrorState = stDumpRawValue defaultRawDecoder = AnyDecoder() supportIndefLength = True @@ -1509,7 +1527,9 @@ class Decoder(object): break if state is stTryAsExplicitTag: - if tagSet and tagSet[0].tagFormat == tag.tagFormatConstructed and tagSet[0].tagClass != tag.tagClassUniversal: + if (tagSet and + tagSet[0].tagFormat == tag.tagFormatConstructed and + tagSet[0].tagClass != tag.tagClassUniversal): # Assume explicit tagging concreteDecoder = explicitTagDecoder state = stDecodeValue diff --git a/tests/codec/ber/test_decoder.py b/tests/codec/ber/test_decoder.py index 8b6d590..bff246e 100644 --- a/tests/codec/ber/test_decoder.py +++ b/tests/codec/ber/test_decoder.py @@ -1429,6 +1429,38 @@ class NonStringDecoderTestCase(BaseTestCase): assert self.s == s +class ErrorOnDecodingTestCase(BaseTestCase): + + def testErrorCondition(self): + decode = decoder.Decoder(decoder.tagMap, decoder.typeMap) + + try: + asn1Object, rest = decode(str2octs('abc')) + + except PyAsn1Error: + exc = sys.exc_info()[1] + assert (isinstance(exc, PyAsn1Error), + 'Unexpected exception raised %r' % (exc,)) + + else: + assert False, 'Unexpected decoder result %r' % (asn1Object,) + + def testRawDump(self): + decode = decoder.Decoder(decoder.tagMap, decoder.typeMap) + + decode.defaultErrorState = decoder.stDumpRawValue + + asn1Object, rest = decode(ints2octs( + (31, 8, 2, 1, 1, 131, 3, 2, 1, 12))) + + assert (isinstance(asn1Object, univ.Any), + 'Unexpected raw dump type %r' % (asn1Object,)) + assert (asn1Object.asNumbers() == (31, 8, 2, 1, 1), + 'Unexpected raw dump value %r' % (asn1Object,)) + assert (rest == ints2octs((131, 3, 2, 1, 12)), + 'Unexpected rest of substrate after raw dump %r' % rest) + + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == '__main__': -- cgit v1.2.1