diff options
Diffstat (limited to 'pyasn1/codec/ber/decoder.py')
-rw-r--r-- | pyasn1/codec/ber/decoder.py | 93 |
1 files changed, 75 insertions, 18 deletions
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py index 591bbc4..3f2d180 100644 --- a/pyasn1/codec/ber/decoder.py +++ b/pyasn1/codec/ber/decoder.py @@ -567,6 +567,7 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder): return asn1Object, tail asn1Object = asn1Spec.clone() + asn1Object.clear() if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId): @@ -670,18 +671,35 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder): LOG('resolved open type %r by governing ' 'value %r' % (openType, governingValue)) - component, rest = decodeFun( - asn1Object.getComponentByPosition(idx).asOctets(), - asn1Spec=openType - ) + containerValue = asn1Object.getComponentByPosition(idx) + + if containerValue.typeId in ( + univ.SetOf.typeId, univ.SequenceOf.typeId): + + for pos, containerElement in enumerate( + containerValue): + + component, rest = decodeFun( + containerValue[pos].asOctets(), + asn1Spec=openType, **options + ) - asn1Object.setComponentByPosition(idx, component) + containerValue[pos] = component + + else: + component, rest = decodeFun( + asn1Object.getComponentByPosition(idx).asOctets(), + asn1Spec=openType, **options + ) + + asn1Object.setComponentByPosition(idx, component) else: asn1Object.verifySizeSpec() else: asn1Object = asn1Spec.clone() + asn1Object.clear() componentType = asn1Spec.componentType @@ -723,10 +741,12 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder): if asn1Spec is None: return self._decodeComponents( - substrate, tagSet=tagSet, decodeFun=decodeFun, allowEoo=True, **options + substrate, tagSet=tagSet, decodeFun=decodeFun, + **dict(options, allowEoo=True) ) asn1Object = asn1Spec.clone() + asn1Object.clear() if asn1Spec.typeId in (univ.Sequence.typeId, univ.Set.typeId): @@ -796,7 +816,7 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder): if not namedTypes.requiredComponents.issubset(seenIndices): raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__) - if namedTypes.hasOpenTypes: + if namedTypes.hasOpenTypes: openTypes = options.get('openTypes', {}) @@ -834,19 +854,36 @@ class UniversalConstructedTypeDecoder(AbstractConstructedDecoder): LOG('resolved open type %r by governing ' 'value %r' % (openType, governingValue)) - component, rest = decodeFun( - asn1Object.getComponentByPosition(idx).asOctets(), - asn1Spec=openType, allowEoo=True - ) + containerValue = asn1Object.getComponentByPosition(idx) - if component is not eoo.endOfOctets: - asn1Object.setComponentByPosition(idx, component) + if containerValue.typeId in ( + univ.SetOf.typeId, univ.SequenceOf.typeId): + + for pos, containerElement in enumerate( + containerValue): + + component, rest = decodeFun( + containerValue[pos].asOctets(), + asn1Spec=openType, **dict(options, allowEoo=True) + ) + + containerValue[pos] = component + + else: + component, rest = decodeFun( + asn1Object.getComponentByPosition(idx).asOctets(), + asn1Spec=openType, **dict(options, allowEoo=True) + ) + + if component is not eoo.endOfOctets: + asn1Object.setComponentByPosition(idx, component) else: asn1Object.verifySizeSpec() else: asn1Object = asn1Spec.clone() + asn1Object.clear() componentType = asn1Spec.componentType @@ -1012,7 +1049,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 @@ -1034,7 +1080,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 @@ -1204,7 +1259,7 @@ for typeDecoder in tagMap.values(): class Decoder(object): defaultErrorState = stErrorCondition - # defaultErrorState = stDumpRawValue + #defaultErrorState = stDumpRawValue defaultRawDecoder = AnyDecoder() supportIndefLength = True @@ -1505,7 +1560,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 @@ -1563,7 +1620,7 @@ class Decoder(object): #: #: Raises #: ------ -#: :py:class:`~pyasn1.error.PyAsn1Error` +#: ~pyasn1.error.PyAsn1Error, ~pyasn1.error.SubstrateUnderrunError #: On decoding errors #: #: Examples |