diff --git a/CHANGES.rst b/CHANGES.rst index 95b832997e5c7f91a8e3c566621ca43b89002801_Q0hBTkdFUy5yc3Q=..9688c23390ece4aa91957e500ef1c30f4af61f96_Q0hBTkdFUy5yc3Q= 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,6 +6,8 @@ for more functionality when in use. Specifically, the global LOG object can easily be used from any function/method, not just from codec main loop as it used to be. +- More debug logging added to BER family of codecs to ease encoding + problems troubleshooting. Revision 0.4.4, released 26-07-2018 ----------------------------------- diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py index 95b832997e5c7f91a8e3c566621ca43b89002801_cHlhc24xL2NvZGVjL2Jlci9kZWNvZGVyLnB5..9688c23390ece4aa91957e500ef1c30f4af61f96_cHlhc24xL2NvZGVjL2Jlci9kZWNvZGVyLnB5 100644 --- a/pyasn1/codec/ber/decoder.py +++ b/pyasn1/codec/ber/decoder.py @@ -73,8 +73,8 @@ value, _ = decodeFun(head, asn1Spec, tagSet, length, **options) if LOG: - LOG('explicit tag container carries %d octets of trailing payload (will be lost!): %s' % ( - len(_), debug.hexdump(_))) + LOG('explicit tag container carries %d octets of trailing payload ' + '(will be lost!): %s' % (len(_), debug.hexdump(_))) return value, tail @@ -126,7 +126,8 @@ protoComponent = univ.Boolean(0) def _createComponent(self, asn1Spec, tagSet, value, **options): - return IntegerDecoder._createComponent(self, asn1Spec, tagSet, value and 1 or 0, **options) + return IntegerDecoder._createComponent( + self, asn1Spec, tagSet, value and 1 or 0, **options) class BitStringDecoder(AbstractSimpleDecoder): @@ -140,8 +141,8 @@ head, tail = substrate[:length], substrate[length:] if substrateFun: - return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options), - substrate, length) + return substrateFun(self._createComponent( + asn1Spec, tagSet, noValue, **options), substrate, length) if not head: raise error.PyAsn1Error('Empty BIT STRING substrate') @@ -154,8 +155,9 @@ 'Trailing bits overflow %s' % trailingBits ) - value = self.protoComponent.fromOctetString(head[1:], internalFormat=True, padding=trailingBits) + value = self.protoComponent.fromOctetString( + head[1:], internalFormat=True, padding=trailingBits) return self._createComponent(asn1Spec, tagSet, value, **options), tail if not self.supportConstructedForm: @@ -158,8 +160,12 @@ return self._createComponent(asn1Spec, tagSet, value, **options), tail if not self.supportConstructedForm: - raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__) + raise error.PyAsn1Error('Constructed encoding form prohibited ' + 'at %s' % self.__class__.__name__) + + if LOG: + LOG('assembling constructed serialization') # All inner fragments are of the same type, treat them as octet string substrateFun = self.substrateCollector @@ -240,6 +246,9 @@ if not self.supportConstructedForm: raise error.PyAsn1Error('Constructed encoding form prohibited at %s' % self.__class__.__name__) + if LOG: + LOG('assembling constructed serialization') + # All inner fragments are of the same type, treat them as octet string substrateFun = self.substrateCollector @@ -273,4 +282,5 @@ allowEoo=True, **options) if component is eoo.endOfOctets: break + header += component @@ -276,4 +286,5 @@ header += component + else: raise error.SubstrateUnderrunError( 'No EOO seen before substrate ends' @@ -380,4 +391,8 @@ if fo & 0x80: # binary encoding if not head: raise error.PyAsn1Error("Incomplete floating-point value") + + if LOG: + LOG('decoding binary encoded REAL') + n = (fo & 0x03) + 1 @@ -383,4 +398,5 @@ n = (fo & 0x03) + 1 + if n == 4: n = oct2int(head[0]) head = head[1:] @@ -384,4 +400,5 @@ if n == 4: n = oct2int(head[0]) head = head[1:] + eo, head = head[:n], head[n:] @@ -387,3 +404,4 @@ eo, head = head[:n], head[n:] + if not eo or not head: raise error.PyAsn1Error('Real exponent screwed') @@ -388,3 +406,4 @@ if not eo or not head: raise error.PyAsn1Error('Real exponent screwed') + e = oct2int(eo[0]) & 0x80 and -1 or 0 @@ -390,5 +409,6 @@ e = oct2int(eo[0]) & 0x80 and -1 or 0 + while eo: # exponent e <<= 8 e |= oct2int(eo[0]) eo = eo[1:] @@ -391,5 +411,6 @@ while eo: # exponent e <<= 8 e |= oct2int(eo[0]) eo = eo[1:] + b = fo >> 4 & 0x03 # base bits @@ -395,3 +416,4 @@ b = fo >> 4 & 0x03 # base bits + if b > 2: raise error.PyAsn1Error('Illegal Real base') @@ -396,4 +418,5 @@ if b > 2: raise error.PyAsn1Error('Illegal Real base') + if b == 1: # encbase = 8 e *= 3 @@ -398,5 +421,6 @@ if b == 1: # encbase = 8 e *= 3 + elif b == 2: # encbase = 16 e *= 4 p = 0 @@ -400,7 +424,8 @@ elif b == 2: # encbase = 16 e *= 4 p = 0 + while head: # value p <<= 8 p |= oct2int(head[0]) head = head[1:] @@ -403,6 +428,7 @@ while head: # value p <<= 8 p |= oct2int(head[0]) head = head[1:] + if fo & 0x40: # sign bit p = -p @@ -407,5 +433,6 @@ if fo & 0x40: # sign bit p = -p + sf = fo >> 2 & 0x03 # scale bits p *= 2 ** sf value = (p, 2, e) @@ -409,4 +436,5 @@ sf = fo >> 2 & 0x03 # scale bits p *= 2 ** sf value = (p, 2, e) + elif fo & 0x40: # infinite value @@ -412,2 +440,5 @@ elif fo & 0x40: # infinite value + if LOG: + LOG('decoding infinite REAL') + value = fo & 0x01 and '-inf' or 'inf' @@ -413,4 +444,5 @@ value = fo & 0x01 and '-inf' or 'inf' + elif fo & 0xc0 == 0: # character encoding if not head: raise error.PyAsn1Error("Incomplete floating-point value") @@ -414,6 +446,10 @@ elif fo & 0xc0 == 0: # character encoding if not head: raise error.PyAsn1Error("Incomplete floating-point value") + + if LOG: + LOG('decoding character encoded REAL') + try: if fo & 0x3 == 0x1: # NR1 value = (int(head), 10, 0) @@ -417,5 +453,6 @@ try: if fo & 0x3 == 0x1: # NR1 value = (int(head), 10, 0) + elif fo & 0x3 == 0x2: # NR2 value = float(head) @@ -420,4 +457,5 @@ elif fo & 0x3 == 0x2: # NR2 value = float(head) + elif fo & 0x3 == 0x3: # NR3 value = float(head) @@ -422,6 +460,7 @@ elif fo & 0x3 == 0x3: # NR3 value = float(head) + else: raise error.SubstrateUnderrunError( 'Unknown NR (tag %s)' % fo ) @@ -424,8 +463,9 @@ else: raise error.SubstrateUnderrunError( 'Unknown NR (tag %s)' % fo ) + except ValueError: raise error.SubstrateUnderrunError( 'Bad character Real syntax' ) @@ -428,8 +468,9 @@ except ValueError: raise error.SubstrateUnderrunError( 'Bad character Real syntax' ) + else: raise error.SubstrateUnderrunError( 'Unknown encoding (tag %s)' % fo ) @@ -432,7 +473,8 @@ else: raise error.SubstrateUnderrunError( 'Unknown encoding (tag %s)' % fo ) + return self._createComponent(asn1Spec, tagSet, value, **options), tail @@ -453,7 +495,8 @@ def _decodeComponents(self, substrate, tagSet=None, decodeFun=None, **options): components = [] componentTypes = set() + while substrate: component, substrate = decodeFun(substrate, **options) if component is eoo.endOfOctets: break @@ -456,7 +499,8 @@ while substrate: component, substrate = decodeFun(substrate, **options) if component is eoo.endOfOctets: break + components.append(component) componentTypes.add(component.tagSet) @@ -466,6 +510,7 @@ # * otherwise -> likely SEQUENCE OF/SET OF if len(componentTypes) > 1: protoComponent = self.protoRecordComponent + else: protoComponent = self.protoSequenceComponent @@ -475,6 +520,10 @@ tagSet=tag.TagSet(protoComponent.tagSet.baseTag, *tagSet.superTags) ) + if LOG: + LOG('guessed %r container type (pass `asn1Spec` to guide the ' + 'decoder)' % asn1Object) + for idx, component in enumerate(components): asn1Object.setComponentByPosition( idx, component, @@ -496,5 +545,6 @@ if substrateFun is not None: if asn1Spec is not None: asn1Object = asn1Spec.clone() + elif self.protoComponent is not None: asn1Object = self.protoComponent.clone(tagSet=tagSet) @@ -499,5 +549,6 @@ elif self.protoComponent is not None: asn1Object = self.protoComponent.clone(tagSet=tagSet) + else: asn1Object = self.protoRecordComponent, self.protoSequenceComponent @@ -507,4 +558,5 @@ asn1Object, trailing = self._decodeComponents( head, tagSet=tagSet, decodeFun=decodeFun, **options ) + if trailing: @@ -510,5 +562,8 @@ if trailing: - raise error.PyAsn1Error('Unused trailing %d octets encountered' % len(trailing)) + if LOG: + LOG('Unused trailing %d octets encountered: %s' % ( + len(trailing), debug.hexdump(trailing))) + return asn1Object, tail asn1Object = asn1Spec.clone() @@ -520,8 +575,13 @@ isSetType = asn1Spec.typeId == univ.Set.typeId isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault + if LOG: + LOG('decoding %sdeterministic %s type %r chosen by type ID' % ( + not isDeterministic and 'non-' or '', isSetType and 'SET' or '', + asn1Spec)) + seenIndices = set() idx = 0 while head: if not namedTypes: componentType = None @@ -523,7 +583,8 @@ seenIndices = set() idx = 0 while head: if not namedTypes: componentType = None + elif isSetType: componentType = namedTypes.tagMapUnique @@ -528,6 +589,7 @@ elif isSetType: componentType = namedTypes.tagMapUnique + else: try: if isDeterministic: componentType = namedTypes[idx].asn1Object @@ -530,6 +592,7 @@ else: try: if isDeterministic: componentType = namedTypes[idx].asn1Object + elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted: componentType = namedTypes.getTagMapNearPosition(idx) @@ -534,4 +597,5 @@ elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted: componentType = namedTypes.getTagMapNearPosition(idx) + else: componentType = namedTypes[idx].asn1Object @@ -536,5 +600,6 @@ else: componentType = namedTypes[idx].asn1Object + except IndexError: raise error.PyAsn1Error( 'Excessive components decoded at %r' % (asn1Spec,) @@ -545,6 +610,7 @@ if not isDeterministic and namedTypes: if isSetType: idx = namedTypes.getPositionByType(component.effectiveTagSet) + elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted: idx = namedTypes.getPositionNearType(component.effectiveTagSet, idx) @@ -557,5 +623,8 @@ seenIndices.add(idx) idx += 1 + if LOG: + LOG('seen component indices %s' % seenIndices) + if namedTypes: if not namedTypes.requiredComponents.issubset(seenIndices): @@ -560,8 +629,10 @@ if namedTypes: if not namedTypes.requiredComponents.issubset(seenIndices): - raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__) + raise error.PyAsn1Error( + 'ASN.1 object %s has uninitialized ' + 'components' % asn1Object.__class__.__name__) if namedTypes.hasOpenTypes: openTypes = options.get('openTypes', {}) @@ -563,8 +634,11 @@ if namedTypes.hasOpenTypes: openTypes = options.get('openTypes', {}) + if LOG: + LOG('using open types map: %r' % openTypes) + if openTypes or options.get('decodeOpenTypes', False): for idx, namedType in enumerate(namedTypes.namedTypes): @@ -587,5 +661,8 @@ openType = namedType.openType[governingValue] except KeyError: + if LOG: + LOG('failed to resolve open type by governing ' + 'value %r' % (governingValue,)) continue @@ -590,5 +667,9 @@ continue + if LOG: + LOG('resolved open type %r by governing ' + 'value %r' % (openType, governingValue)) + component, rest = decodeFun( asn1Object.getComponentByPosition(idx).asOctets(), asn1Spec=openType @@ -604,6 +685,9 @@ componentType = asn1Spec.componentType + if LOG: + LOG('decoding type %r chosen by given `asn1Spec`' % componentType) + idx = 0 while head: @@ -613,6 +697,7 @@ verifyConstraints=False, matchTags=False, matchConstraints=False ) + idx += 1 return asn1Object, tail @@ -627,5 +712,6 @@ if substrateFun is not None: if asn1Spec is not None: asn1Object = asn1Spec.clone() + elif self.protoComponent is not None: asn1Object = self.protoComponent.clone(tagSet=tagSet) @@ -630,5 +716,6 @@ elif self.protoComponent is not None: asn1Object = self.protoComponent.clone(tagSet=tagSet) + else: asn1Object = self.protoRecordComponent, self.protoSequenceComponent @@ -648,8 +735,13 @@ isSetType = asn1Object.typeId == univ.Set.typeId isDeterministic = not isSetType and not namedTypes.hasOptionalOrDefault + if LOG: + LOG('decoding %sdeterministic %s type %r chosen by type ID' % ( + not isDeterministic and 'non-' or '', isSetType and 'SET' or '', + asn1Spec)) + seenIndices = set() idx = 0 while substrate: if len(namedTypes) <= idx: asn1Spec = None @@ -651,7 +743,8 @@ seenIndices = set() idx = 0 while substrate: if len(namedTypes) <= idx: asn1Spec = None + elif isSetType: asn1Spec = namedTypes.tagMapUnique @@ -656,6 +749,7 @@ elif isSetType: asn1Spec = namedTypes.tagMapUnique + else: try: if isDeterministic: asn1Spec = namedTypes[idx].asn1Object @@ -658,6 +752,7 @@ else: try: if isDeterministic: asn1Spec = namedTypes[idx].asn1Object + elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted: asn1Spec = namedTypes.getTagMapNearPosition(idx) @@ -662,4 +757,5 @@ elif namedTypes[idx].isOptional or namedTypes[idx].isDefaulted: asn1Spec = namedTypes.getTagMapNearPosition(idx) + else: asn1Spec = namedTypes[idx].asn1Object @@ -664,5 +760,6 @@ else: asn1Spec = namedTypes[idx].asn1Object + except IndexError: raise error.PyAsn1Error( 'Excessive components decoded at %r' % (asn1Object,) @@ -692,9 +789,12 @@ 'No EOO seen before substrate ends' ) + if LOG: + LOG('seen component indices %s' % seenIndices) + if namedTypes: if not namedTypes.requiredComponents.issubset(seenIndices): raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__) if namedTypes.hasOpenTypes: @@ -695,10 +795,13 @@ if namedTypes: if not namedTypes.requiredComponents.issubset(seenIndices): raise error.PyAsn1Error('ASN.1 object %s has uninitialized components' % asn1Object.__class__.__name__) if namedTypes.hasOpenTypes: - openTypes = options.get('openTypes', None) + openTypes = options.get('openTypes', {}) + + if LOG: + LOG('using open types map: %r' % openTypes) if openTypes or options.get('decodeOpenTypes', False): @@ -722,5 +825,8 @@ openType = namedType.openType[governingValue] except KeyError: + if LOG: + LOG('failed to resolve open type by governing ' + 'value %r' % (governingValue,)) continue @@ -725,5 +831,9 @@ continue + if LOG: + LOG('resolved open type %r by governing ' + 'value %r' % (openType, governingValue)) + component, rest = decodeFun( asn1Object.getComponentByPosition(idx).asOctets(), asn1Spec=openType, allowEoo=True @@ -740,6 +850,9 @@ componentType = asn1Spec.componentType + if LOG: + LOG('decoding type %r chosen by given `asn1Spec`' % componentType) + idx = 0 while substrate: @@ -753,4 +866,5 @@ verifyConstraints=False, matchTags=False, matchConstraints=False ) + idx += 1 @@ -756,4 +870,5 @@ idx += 1 + else: raise error.SubstrateUnderrunError( 'No EOO seen before substrate ends' @@ -800,9 +915,10 @@ if asn1Spec is None: asn1Object = self.protoComponent.clone(tagSet=tagSet) + else: asn1Object = asn1Spec.clone() if substrateFun: return substrateFun(asn1Object, substrate, length) @@ -803,12 +919,15 @@ else: asn1Object = asn1Spec.clone() if substrateFun: return substrateFun(asn1Object, substrate, length) - if asn1Object.tagSet == tagSet: # explicitly tagged Choice + if asn1Object.tagSet == tagSet: + if LOG: + LOG('decoding %s as explicitly tagged CHOICE' % (tagSet,)) + component, head = decodeFun( head, asn1Object.componentTagMap, **options ) else: @@ -810,8 +929,11 @@ component, head = decodeFun( head, asn1Object.componentTagMap, **options ) else: + if LOG: + LOG('decoding %s as untagged CHOICE' % (tagSet,)) + component, head = decodeFun( head, asn1Object.componentTagMap, tagSet, length, state, **options @@ -819,6 +941,9 @@ effectiveTagSet = component.effectiveTagSet + if LOG: + LOG('decoded component %s, effective tag set %s' % (component, effectiveTagSet)) + asn1Object.setComponentByType( effectiveTagSet, component, verifyConstraints=False, @@ -840,7 +965,10 @@ if substrateFun: return substrateFun(asn1Object, substrate, length) - if asn1Object.tagSet == tagSet: # explicitly tagged Choice + if asn1Object.tagSet == tagSet: + if LOG: + LOG('decoding %s as explicitly tagged CHOICE' % (tagSet,)) + component, substrate = decodeFun( substrate, asn1Object.componentType.tagMapUnique, **options ) @@ -844,7 +972,8 @@ component, substrate = decodeFun( substrate, asn1Object.componentType.tagMapUnique, **options ) + # eat up EOO marker eooMarker, substrate = decodeFun( substrate, allowEoo=True, **options ) @@ -847,8 +976,9 @@ # eat up EOO marker eooMarker, substrate = decodeFun( substrate, allowEoo=True, **options ) + if eooMarker is not eoo.endOfOctets: raise error.PyAsn1Error('No EOO seen before substrate ends') else: @@ -851,7 +981,10 @@ if eooMarker is not eoo.endOfOctets: raise error.PyAsn1Error('No EOO seen before substrate ends') else: + if LOG: + LOG('decoding %s as untagged CHOICE' % (tagSet,)) + component, substrate = decodeFun( substrate, asn1Object.componentType.tagMapUnique, tagSet, length, state, **options @@ -859,6 +992,9 @@ effectiveTagSet = component.effectiveTagSet + if LOG: + LOG('decoded component %s, effective tag set %s' % (component, effectiveTagSet)) + asn1Object.setComponentByType( effectiveTagSet, component, verifyConstraints=False, @@ -883,6 +1019,9 @@ length += len(fullSubstrate) - len(substrate) substrate = fullSubstrate + if LOG: + LOG('decoding as untagged ANY, substrate %s' % debug.hexdump(substrate)) + if substrateFun: return substrateFun(self._createComponent(asn1Spec, tagSet, noValue, **options), substrate, length) @@ -898,9 +1037,13 @@ if asn1Spec is not None and tagSet == asn1Spec.tagSet: # tagged Any type -- consume header substrate header = null + + if LOG: + LOG('decoding as tagged ANY') + else: fullSubstrate = options['fullSubstrate'] # untagged Any, recover header substrate header = fullSubstrate[:-len(substrate)] @@ -901,9 +1044,12 @@ else: fullSubstrate = options['fullSubstrate'] # untagged Any, recover header substrate header = fullSubstrate[:-len(substrate)] + if LOG: + LOG('decoding as untagged ANY, header substrate %s' % debug.hexdump(header)) + # Any components do not inherit initial tag asn1Spec = self.protoComponent @@ -911,6 +1057,9 @@ asn1Object = self._createComponent(asn1Spec, tagSet, noValue, **options) return substrateFun(asn1Object, header + substrate, length + len(header)) + if LOG: + LOG('assembling constructed serialization') + # All inner fragments are of the same type, treat them as octet string substrateFun = self.substrateCollector @@ -920,4 +1069,5 @@ allowEoo=True, **options) if component is eoo.endOfOctets: break + header += component @@ -923,5 +1073,6 @@ header += component + else: raise error.SubstrateUnderrunError( 'No EOO seen before substrate ends' ) @@ -924,6 +1075,7 @@ else: raise error.SubstrateUnderrunError( 'No EOO seen before substrate ends' ) + if substrateFun: return header, substrate @@ -928,5 +1080,6 @@ if substrateFun: return header, substrate + else: return self._createComponent(asn1Spec, tagSet, header, **options), substrate @@ -1091,8 +1244,9 @@ fullSubstrate = substrate while state is not stStop: + if state is stDecodeTag: if not substrate: raise error.SubstrateUnderrunError( 'Short octet stream on tag decoding' ) @@ -1094,9 +1248,10 @@ if state is stDecodeTag: if not substrate: raise error.SubstrateUnderrunError( 'Short octet stream on tag decoding' ) + # Decode tag isShortTag = True firstOctet = substrate[0] substrate = substrate[1:] @@ -1099,6 +1254,7 @@ # Decode tag isShortTag = True firstOctet = substrate[0] substrate = substrate[1:] + try: lastTag = tagCache[firstOctet] @@ -1103,7 +1259,8 @@ try: lastTag = tagCache[firstOctet] + except KeyError: integerTag = oct2int(firstOctet) tagClass = integerTag & 0xC0 tagFormat = integerTag & 0x20 tagId = integerTag & 0x1F @@ -1105,9 +1262,10 @@ except KeyError: integerTag = oct2int(firstOctet) tagClass = integerTag & 0xC0 tagFormat = integerTag & 0x20 tagId = integerTag & 0x1F + if tagId == 0x1F: isShortTag = False lengthOctetIdx = 0 tagId = 0 @@ -1110,7 +1268,8 @@ if tagId == 0x1F: isShortTag = False lengthOctetIdx = 0 tagId = 0 + try: while True: integerTag = oct2int(substrate[lengthOctetIdx]) @@ -1119,4 +1278,5 @@ tagId |= (integerTag & 0x7F) if not integerTag & 0x80: break + substrate = substrate[lengthOctetIdx:] @@ -1122,5 +1282,6 @@ substrate = substrate[lengthOctetIdx:] + except IndexError: raise error.SubstrateUnderrunError( 'Short octet stream on long tag decoding' ) @@ -1123,7 +1284,8 @@ except IndexError: raise error.SubstrateUnderrunError( 'Short octet stream on long tag decoding' ) + lastTag = tag.Tag( tagClass=tagClass, tagFormat=tagFormat, tagId=tagId ) @@ -1127,6 +1289,7 @@ lastTag = tag.Tag( tagClass=tagClass, tagFormat=tagFormat, tagId=tagId ) + if isShortTag: # cache short tags tagCache[firstOctet] = lastTag @@ -1130,7 +1293,8 @@ if isShortTag: # cache short tags tagCache[firstOctet] = lastTag + if tagSet is None: if isShortTag: try: tagSet = tagSetCache[firstOctet] @@ -1133,10 +1297,11 @@ if tagSet is None: if isShortTag: try: tagSet = tagSetCache[firstOctet] + except KeyError: # base tag not recovered tagSet = tag.TagSet((), lastTag) tagSetCache[firstOctet] = tagSet else: tagSet = tag.TagSet((), lastTag) @@ -1137,8 +1302,9 @@ except KeyError: # base tag not recovered tagSet = tag.TagSet((), lastTag) tagSetCache[firstOctet] = tagSet else: tagSet = tag.TagSet((), lastTag) + else: tagSet = lastTag + tagSet @@ -1143,3 +1309,4 @@ else: tagSet = lastTag + tagSet + state = stDecodeLength @@ -1145,3 +1312,4 @@ state = stDecodeLength + if LOG: LOG('tag decoded into %s, decoding length' % tagSet) @@ -1146,8 +1314,9 @@ if LOG: LOG('tag decoded into %s, decoding length' % tagSet) + if state is stDecodeLength: # Decode length if not substrate: raise error.SubstrateUnderrunError( 'Short octet stream on length decoding' ) @@ -1148,7 +1317,8 @@ if state is stDecodeLength: # Decode length if not substrate: raise error.SubstrateUnderrunError( 'Short octet stream on length decoding' ) + firstOctet = oct2int(substrate[0]) @@ -1154,4 +1324,5 @@ firstOctet = oct2int(substrate[0]) + if firstOctet < 128: size = 1 length = firstOctet @@ -1155,6 +1326,7 @@ if firstOctet < 128: size = 1 length = firstOctet + elif firstOctet > 128: size = firstOctet & 0x7F # encoded in size bytes @@ -1165,8 +1337,9 @@ raise error.SubstrateUnderrunError( '%s<%s at %s' % (size, len(encodedLength), tagSet) ) + length = 0 for lengthOctet in encodedLength: length <<= 8 length |= lengthOctet size += 1 @@ -1168,10 +1341,11 @@ length = 0 for lengthOctet in encodedLength: length <<= 8 length |= lengthOctet size += 1 + else: size = 1 length = -1 substrate = substrate[size:] @@ -1173,8 +1347,9 @@ else: size = 1 length = -1 substrate = substrate[size:] + if length == -1: if not self.supportIndefLength: raise error.PyAsn1Error('Indefinite length encoding not supported by this codec') @@ -1178,6 +1353,7 @@ if length == -1: if not self.supportIndefLength: raise error.PyAsn1Error('Indefinite length encoding not supported by this codec') + else: if len(substrate) < length: raise error.SubstrateUnderrunError('%d-octet short' % (length - len(substrate))) @@ -1181,4 +1357,5 @@ else: if len(substrate) < length: raise error.SubstrateUnderrunError('%d-octet short' % (length - len(substrate))) + state = stGetValueDecoder @@ -1184,3 +1361,4 @@ state = stGetValueDecoder + if LOG: LOG('value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or substrate[:length]))) @@ -1185,5 +1363,6 @@ if LOG: LOG('value length decoded into %d, payload substrate is: %s' % (length, debug.hexdump(length == -1 and substrate or substrate[:length]))) + if state is stGetValueDecoder: if asn1Spec is None: state = stGetValueDecoderByTag @@ -1187,6 +1366,7 @@ if state is stGetValueDecoder: if asn1Spec is None: state = stGetValueDecoderByTag + else: state = stGetValueDecoderByAsn1Spec # @@ -1208,5 +1388,6 @@ if state is stGetValueDecoderByTag: try: concreteDecoder = tagMap[tagSet] + except KeyError: concreteDecoder = None @@ -1211,4 +1392,5 @@ except KeyError: concreteDecoder = None + if concreteDecoder: state = stDecodeValue @@ -1213,5 +1395,6 @@ if concreteDecoder: state = stDecodeValue + else: try: concreteDecoder = tagMap[tagSet[:1]] @@ -1215,5 +1398,6 @@ else: try: concreteDecoder = tagMap[tagSet[:1]] + except KeyError: concreteDecoder = None @@ -1218,6 +1402,7 @@ except KeyError: concreteDecoder = None + if concreteDecoder: state = stDecodeValue else: state = stTryAsExplicitTag @@ -1220,7 +1405,8 @@ if concreteDecoder: state = stDecodeValue else: state = stTryAsExplicitTag + if LOG: LOG('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag')) debug.scope.push(concreteDecoder is None and '?' or concreteDecoder.protoComponent.__class__.__name__) @@ -1224,4 +1410,5 @@ if LOG: LOG('codec %s chosen by a built-in type, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag')) debug.scope.push(concreteDecoder is None and '?' or concreteDecoder.protoComponent.__class__.__name__) + if state is stGetValueDecoderByAsn1Spec: @@ -1227,4 +1414,5 @@ if state is stGetValueDecoderByAsn1Spec: + if asn1Spec.__class__ is tagmap.TagMap: try: chosenSpec = asn1Spec[tagSet] @@ -1228,5 +1416,6 @@ if asn1Spec.__class__ is tagmap.TagMap: try: chosenSpec = asn1Spec[tagSet] + except KeyError: chosenSpec = None @@ -1231,4 +1420,5 @@ except KeyError: chosenSpec = None + if LOG: LOG('candidate ASN.1 spec is a map of:') @@ -1233,4 +1423,5 @@ if LOG: LOG('candidate ASN.1 spec is a map of:') + for firstOctet, v in asn1Spec.presentTypes.items(): LOG(' %s -> %s' % (firstOctet, v.__class__.__name__)) @@ -1235,7 +1426,8 @@ for firstOctet, v in asn1Spec.presentTypes.items(): LOG(' %s -> %s' % (firstOctet, v.__class__.__name__)) + if asn1Spec.skipTypes: LOG('but neither of: ') for firstOctet, v in asn1Spec.skipTypes.items(): LOG(' %s -> %s' % (firstOctet, v.__class__.__name__)) LOG('new candidate ASN.1 spec is %s, chosen by %s' % (chosenSpec is None and '<none>' or chosenSpec.prettyPrintType(), tagSet)) @@ -1237,9 +1429,10 @@ if asn1Spec.skipTypes: LOG('but neither of: ') for firstOctet, v in asn1Spec.skipTypes.items(): LOG(' %s -> %s' % (firstOctet, v.__class__.__name__)) LOG('new candidate ASN.1 spec is %s, chosen by %s' % (chosenSpec is None and '<none>' or chosenSpec.prettyPrintType(), tagSet)) + elif tagSet == asn1Spec.tagSet or tagSet in asn1Spec.tagMap: chosenSpec = asn1Spec if LOG: LOG('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__) @@ -1242,7 +1435,8 @@ elif tagSet == asn1Spec.tagSet or tagSet in asn1Spec.tagMap: chosenSpec = asn1Spec if LOG: LOG('candidate ASN.1 spec is %s' % asn1Spec.__class__.__name__) + else: chosenSpec = None @@ -1250,5 +1444,6 @@ try: # ambiguous type or just faster codec lookup concreteDecoder = typeMap[chosenSpec.typeId] + if LOG: LOG('value decoder chosen for an ambiguous type by type ID %s' % (chosenSpec.typeId,)) @@ -1253,8 +1448,9 @@ if LOG: LOG('value decoder chosen for an ambiguous type by type ID %s' % (chosenSpec.typeId,)) + except KeyError: # use base type for codec lookup to recover untagged types baseTagSet = tag.TagSet(chosenSpec.tagSet.baseTag, chosenSpec.tagSet.baseTag) try: # base type or tagged subtype concreteDecoder = tagMap[baseTagSet] @@ -1255,8 +1451,9 @@ except KeyError: # use base type for codec lookup to recover untagged types baseTagSet = tag.TagSet(chosenSpec.tagSet.baseTag, chosenSpec.tagSet.baseTag) try: # base type or tagged subtype concreteDecoder = tagMap[baseTagSet] + if LOG: LOG('value decoder chosen by base %s' % (baseTagSet,)) @@ -1261,4 +1458,5 @@ if LOG: LOG('value decoder chosen by base %s' % (baseTagSet,)) + except KeyError: concreteDecoder = None @@ -1263,5 +1461,6 @@ except KeyError: concreteDecoder = None + if concreteDecoder: asn1Spec = chosenSpec state = stDecodeValue @@ -1265,5 +1464,6 @@ if concreteDecoder: asn1Spec = chosenSpec state = stDecodeValue + else: state = stTryAsExplicitTag @@ -1268,5 +1468,6 @@ else: state = stTryAsExplicitTag + else: concreteDecoder = None state = stTryAsExplicitTag @@ -1270,6 +1471,7 @@ else: concreteDecoder = None state = stTryAsExplicitTag + if LOG: LOG('codec %s chosen by ASN.1 spec, decoding %s' % (state is stDecodeValue and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag')) debug.scope.push(chosenSpec is None and '?' or chosenSpec.__class__.__name__) @@ -1273,6 +1475,7 @@ if LOG: LOG('codec %s chosen by ASN.1 spec, decoding %s' % (state is stDecodeValue and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as explicit tag')) debug.scope.push(chosenSpec is None and '?' or chosenSpec.__class__.__name__) + if state is stDecodeValue: if not options.get('recursiveFlag', True) and not substrateFun: # deprecate this substrateFun = lambda a, b, c: (a, b[:c]) @@ -1286,6 +1489,7 @@ self, substrateFun, **options ) + else: value, substrate = concreteDecoder.valueDecoder( substrate, asn1Spec, @@ -1299,8 +1503,9 @@ state = stStop break + if state is stTryAsExplicitTag: if tagSet and tagSet[0].tagFormat == tag.tagFormatConstructed and tagSet[0].tagClass != tag.tagClassUniversal: # Assume explicit tagging concreteDecoder = explicitTagDecoder state = stDecodeValue @@ -1302,8 +1507,9 @@ if state is stTryAsExplicitTag: if tagSet and tagSet[0].tagFormat == tag.tagFormatConstructed and tagSet[0].tagClass != tag.tagClassUniversal: # Assume explicit tagging concreteDecoder = explicitTagDecoder state = stDecodeValue + else: concreteDecoder = None state = self.defaultErrorState @@ -1307,5 +1513,6 @@ else: concreteDecoder = None state = self.defaultErrorState + if LOG: LOG('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as failure')) @@ -1310,4 +1517,5 @@ if LOG: LOG('codec %s chosen, decoding %s' % (concreteDecoder and concreteDecoder.__class__.__name__ or "<none>", state is stDecodeValue and 'value' or 'as failure')) + if state is stDumpRawValue: concreteDecoder = self.defaultRawDecoder @@ -1312,4 +1520,5 @@ if state is stDumpRawValue: concreteDecoder = self.defaultRawDecoder + if LOG: LOG('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__) @@ -1314,3 +1523,4 @@ if LOG: LOG('codec %s chosen, decoding value' % concreteDecoder.__class__.__name__) + state = stDecodeValue @@ -1316,5 +1526,6 @@ state = stDecodeValue + if state is stErrorCondition: raise error.PyAsn1Error( '%s not in asn1Spec: %r' % (tagSet, asn1Spec) ) @@ -1317,7 +1528,8 @@ if state is stErrorCondition: raise error.PyAsn1Error( '%s not in asn1Spec: %r' % (tagSet, asn1Spec) ) + if LOG: debug.scope.pop() LOG('decoder left scope %s, call completed' % debug.scope) @@ -1321,6 +1533,7 @@ if LOG: debug.scope.pop() LOG('decoder left scope %s, call completed' % debug.scope) + return value, substrate diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py index 95b832997e5c7f91a8e3c566621ca43b89002801_cHlhc24xL2NvZGVjL2Jlci9lbmNvZGVyLnB5..9688c23390ece4aa91957e500ef1c30f4af61f96_cHlhc24xL2NvZGVjL2Jlci9lbmNvZGVyLnB5 100644 --- a/pyasn1/codec/ber/encoder.py +++ b/pyasn1/codec/ber/encoder.py @@ -33,5 +33,6 @@ encodedTag = tagClass | tagFormat if isConstructed: encodedTag |= tag.tagFormatConstructed + if tagId < 31: return encodedTag | tagId, @@ -36,4 +37,5 @@ if tagId < 31: return encodedTag | tagId, + else: substrate = tagId & 0x7f, @@ -38,3 +40,4 @@ else: substrate = tagId & 0x7f, + tagId >>= 7 @@ -40,4 +43,5 @@ tagId >>= 7 + while tagId: substrate = (0x80 | (tagId & 0x7f),) + substrate tagId >>= 7 @@ -41,8 +45,9 @@ while tagId: substrate = (0x80 | (tagId & 0x7f),) + substrate tagId >>= 7 + return (encodedTag | 0x1F,) + substrate def encodeLength(self, length, defMode): if not defMode and self.supportIndefLenMode: return (0x80,) @@ -44,7 +49,8 @@ return (encodedTag | 0x1F,) + substrate def encodeLength(self, length, defMode): if not defMode and self.supportIndefLenMode: return (0x80,) + if length < 0x80: return length, @@ -49,7 +55,8 @@ if length < 0x80: return length, + else: substrate = () while length: substrate = (length & 0xff,) + substrate length >>= 8 @@ -51,6 +58,7 @@ else: substrate = () while length: substrate = (length & 0xff,) + substrate length >>= 8 + substrateLen = len(substrate) @@ -56,3 +64,4 @@ substrateLen = len(substrate) + if substrateLen > 126: raise error.PyAsn1Error('Length octets overflow (%d)' % substrateLen) @@ -57,5 +66,6 @@ if substrateLen > 126: raise error.PyAsn1Error('Length octets overflow (%d)' % substrateLen) + return (0x80 | substrateLen,) + substrate def encodeValue(self, value, asn1Spec, encodeFun, **options): @@ -87,6 +97,11 @@ value, asn1Spec, encodeFun, **options ) + if LOG: + LOG('encoded %svalue %s into %s' % ( + isConstructed and 'constructed ' or '', value, substrate + )) + if not substrate and isConstructed and options.get('ifNotEmpty', False): return substrate @@ -90,7 +105,6 @@ if not substrate and isConstructed and options.get('ifNotEmpty', False): return substrate - # primitive form implies definite mode if not isConstructed: defModeOverride = True @@ -94,4 +108,7 @@ if not isConstructed: defModeOverride = True + if LOG: + LOG('overridden encoding mode into definitive for primitive type') + header = self.encodeTag(singleTag, isConstructed) @@ -97,3 +114,8 @@ header = self.encodeTag(singleTag, isConstructed) + + if LOG: + LOG('encoded %stag %s into %s' % (isConstructed and 'constructed ' or '', + singleTag, debug.hexdump(header))) + header += self.encodeLength(len(substrate), defModeOverride) @@ -98,5 +120,9 @@ header += self.encodeLength(len(substrate), defModeOverride) + if LOG: + LOG('encoded %s octets (tag + payload) into %s' % ( + len(substrate), debug.hexdump(header))) + if isOctets: substrate = ints2octs(header) + substrate @@ -133,6 +159,11 @@ def encodeValue(self, value, asn1Spec, encodeFun, **options): if value == 0: + if LOG: + LOG('encoding %spayload for zero INTEGER' % ( + self.supportCompactZero and 'no ' or '' + )) + # de-facto way to encode zero if self.supportCompactZero: return (), False, False @@ -159,8 +190,11 @@ substrate = alignedValue.asOctets() return int2oct(len(substrate) * 8 - valueLength) + substrate, False, True + if LOG: + LOG('encoding into up to %s-octet chunks' % maxChunkSize) + baseTag = value.tagSet.baseTag # strip off explicit tags if baseTag: tagSet = tag.TagSet(baseTag, baseTag) @@ -162,8 +196,9 @@ baseTag = value.tagSet.baseTag # strip off explicit tags if baseTag: tagSet = tag.TagSet(baseTag, baseTag) + else: tagSet = tag.TagSet() @@ -197,5 +232,6 @@ if not maxChunkSize or len(substrate) <= maxChunkSize: return substrate, False, True - else: + if LOG: + LOG('encoding into up to %s-octet chunks' % maxChunkSize) @@ -201,3 +237,3 @@ - # strip off explicit tags for inner chunks + # strip off explicit tags for inner chunks @@ -203,4 +239,4 @@ - if asn1Spec is None: - baseTag = value.tagSet.baseTag + if asn1Spec is None: + baseTag = value.tagSet.baseTag @@ -206,7 +242,5 @@ - # strip off explicit tags - if baseTag: - tagSet = tag.TagSet(baseTag, baseTag) - else: - tagSet = tag.TagSet() + # strip off explicit tags + if baseTag: + tagSet = tag.TagSet(baseTag, baseTag) @@ -212,3 +246,4 @@ - asn1Spec = value.clone(tagSet=tagSet) + else: + tagSet = tag.TagSet() @@ -214,4 +249,6 @@ - elif not isOctetsType(value): - baseTag = asn1Spec.tagSet.baseTag + asn1Spec = value.clone(tagSet=tagSet) + + elif not isOctetsType(value): + baseTag = asn1Spec.tagSet.baseTag @@ -217,7 +254,5 @@ - # strip off explicit tags - if baseTag: - tagSet = tag.TagSet(baseTag, baseTag) - else: - tagSet = tag.TagSet() + # strip off explicit tags + if baseTag: + tagSet = tag.TagSet(baseTag, baseTag) @@ -223,3 +258,6 @@ - asn1Spec = asn1Spec.clone(tagSet=tagSet) + else: + tagSet = tag.TagSet() + + asn1Spec = asn1Spec.clone(tagSet=tagSet) @@ -225,4 +263,4 @@ - pos = 0 - substrate = null + pos = 0 + substrate = null @@ -228,6 +266,6 @@ - while True: - chunk = value[pos:pos + maxChunkSize] - if not chunk: - break + while True: + chunk = value[pos:pos + maxChunkSize] + if not chunk: + break @@ -233,4 +271,4 @@ - substrate += encodeFun(chunk, asn1Spec, **options) - pos += maxChunkSize + substrate += encodeFun(chunk, asn1Spec, **options) + pos += maxChunkSize @@ -236,5 +274,5 @@ - return substrate, True, True + return substrate, True, True class NullEncoder(AbstractItemEncoder): @@ -270,5 +308,6 @@ oid = (second + 80,) + oid[2:] else: raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,)) + elif first == 2: oid = (second + 80,) + oid[2:] @@ -273,5 +312,6 @@ elif first == 2: oid = (second + 80,) + oid[2:] + else: raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,)) @@ -282,7 +322,8 @@ if 0 <= subOid <= 127: # Optimize for the common case octets += (subOid,) + elif subOid > 127: # Pack large Sub-Object IDs res = (subOid & 0x7f,) subOid >>= 7 @@ -285,7 +326,8 @@ elif subOid > 127: # Pack large Sub-Object IDs res = (subOid & 0x7f,) subOid >>= 7 + while subOid: res = (0x80 | (subOid & 0x7f),) + res subOid >>= 7 @@ -289,5 +331,6 @@ while subOid: res = (0x80 | (subOid & 0x7f),) + res subOid >>= 7 + # Add packed Sub-Object ID to resulted Object ID octets += res @@ -292,5 +335,6 @@ # Add packed Sub-Object ID to resulted Object ID octets += res + else: raise error.PyAsn1Error('Negative OID arc %s at %s' % (subOid, value)) @@ -306,5 +350,6 @@ ms, es = 1, 1 if m < 0: ms = -1 # mantissa sign + if e < 0: es = -1 # exponent sign @@ -309,3 +354,4 @@ if e < 0: es = -1 # exponent sign + m *= ms @@ -311,4 +357,5 @@ m *= ms + if encbase == 8: m *= 2 ** (abs(e) % 3 * es) e = abs(e) // 3 * es @@ -312,6 +359,7 @@ if encbase == 8: m *= 2 ** (abs(e) % 3 * es) e = abs(e) // 3 * es + elif encbase == 16: m *= 2 ** (abs(e) % 4 * es) e = abs(e) // 4 * es @@ -322,6 +370,7 @@ e -= 1 continue break + return ms, int(m), encbase, e def _chooseEncBase(self, value): @@ -329,5 +378,6 @@ encBase = [2, 8, 16] if value.binEncBase in encBase: return self._dropFloatingPoint(m, value.binEncBase, e) + elif self.binEncBase in encBase: return self._dropFloatingPoint(m, self.binEncBase, e) @@ -332,8 +382,9 @@ elif self.binEncBase in encBase: return self._dropFloatingPoint(m, self.binEncBase, e) - # auto choosing base 2/8/16 + + # auto choosing base 2/8/16 mantissa = [m, m, m] exponent = [e, e, e] sign = 1 encbase = 2 e = float('inf') @@ -335,10 +386,11 @@ mantissa = [m, m, m] exponent = [e, e, e] sign = 1 encbase = 2 e = float('inf') + for i in range(3): (sign, mantissa[i], encBase[i], exponent[i]) = self._dropFloatingPoint(mantissa[i], encBase[i], exponent[i]) @@ -340,9 +392,10 @@ for i in range(3): (sign, mantissa[i], encBase[i], exponent[i]) = self._dropFloatingPoint(mantissa[i], encBase[i], exponent[i]) + if abs(exponent[i]) < abs(e) or (abs(exponent[i]) == abs(e) and mantissa[i] < m): e = exponent[i] m = int(mantissa[i]) encbase = encBase[i] @@ -345,7 +398,12 @@ if abs(exponent[i]) < abs(e) or (abs(exponent[i]) == abs(e) and mantissa[i] < m): e = exponent[i] m = int(mantissa[i]) encbase = encBase[i] + + if LOG: + LOG('automatically chosen REAL encoding base %s, sign %s, mantissa %s, ' + 'exponent %s' % (encbase, sign, m, e)) + return sign, m, encbase, e def encodeValue(self, value, asn1Spec, encodeFun, **options): @@ -354,5 +412,6 @@ if value.isPlusInf: return (0x40,), False, False + if value.isMinusInf: return (0x41,), False, False @@ -357,3 +416,4 @@ if value.isMinusInf: return (0x41,), False, False + m, b, e = value @@ -359,3 +419,4 @@ m, b, e = value + if not m: return null, False, True @@ -360,3 +421,4 @@ if not m: return null, False, True + if b == 10: @@ -362,2 +424,5 @@ if b == 10: + if LOG: + LOG('encoding REAL into character form') + return str2octs('\x03%dE%s%d' % (m, e == 0 and '+' or '', e)), False, True @@ -363,4 +428,5 @@ return str2octs('\x03%dE%s%d' % (m, e == 0 and '+' or '', e)), False, True + elif b == 2: fo = 0x80 # binary encoding ms, m, encbase, e = self._chooseEncBase(value) @@ -364,5 +430,6 @@ elif b == 2: fo = 0x80 # binary encoding ms, m, encbase, e = self._chooseEncBase(value) + if ms < 0: # mantissa sign fo |= 0x40 # sign bit @@ -367,7 +434,8 @@ if ms < 0: # mantissa sign fo |= 0x40 # sign bit + # exponent & mantissa normalization if encbase == 2: while m & 0x1 == 0: m >>= 1 e += 1 @@ -369,10 +437,11 @@ # exponent & mantissa normalization if encbase == 2: while m & 0x1 == 0: m >>= 1 e += 1 + elif encbase == 8: while m & 0x7 == 0: m >>= 3 e += 1 fo |= 0x10 @@ -374,10 +443,11 @@ elif encbase == 8: while m & 0x7 == 0: m >>= 3 e += 1 fo |= 0x10 + else: # encbase = 16 while m & 0xf == 0: m >>= 4 e += 1 fo |= 0x20 @@ -379,6 +449,7 @@ else: # encbase = 16 while m & 0xf == 0: m >>= 4 e += 1 fo |= 0x20 + sf = 0 # scale factor @@ -384,4 +455,5 @@ sf = 0 # scale factor + while m & 0x1 == 0: m >>= 1 sf += 1 @@ -385,5 +457,6 @@ while m & 0x1 == 0: m >>= 1 sf += 1 + if sf > 3: raise error.PyAsn1Error('Scale factor overflow') # bug if raised @@ -388,6 +461,7 @@ if sf > 3: raise error.PyAsn1Error('Scale factor overflow') # bug if raised + fo |= sf << 2 eo = null if e == 0 or e == -1: eo = int2oct(e & 0xff) @@ -390,8 +464,9 @@ fo |= sf << 2 eo = null if e == 0 or e == -1: eo = int2oct(e & 0xff) + else: while e not in (0, -1): eo = int2oct(e & 0xff) + eo e >>= 8 @@ -394,6 +469,7 @@ else: while e not in (0, -1): eo = int2oct(e & 0xff) + eo e >>= 8 + if e == 0 and eo and oct2int(eo[0]) & 0x80: eo = int2oct(0) + eo @@ -398,4 +474,5 @@ if e == 0 and eo and oct2int(eo[0]) & 0x80: eo = int2oct(0) + eo + if e == -1 and eo and not (oct2int(eo[0]) & 0x80): eo = int2oct(0xff) + eo @@ -400,5 +477,6 @@ if e == -1 and eo and not (oct2int(eo[0]) & 0x80): eo = int2oct(0xff) + eo + n = len(eo) if n > 0xff: raise error.PyAsn1Error('Real exponent overflow') @@ -402,5 +480,6 @@ n = len(eo) if n > 0xff: raise error.PyAsn1Error('Real exponent overflow') + if n == 1: pass @@ -405,4 +484,5 @@ if n == 1: pass + elif n == 2: fo |= 1 @@ -407,4 +487,5 @@ elif n == 2: fo |= 1 + elif n == 3: fo |= 2 @@ -409,5 +490,6 @@ elif n == 3: fo |= 2 + else: fo |= 3 eo = int2oct(n & 0xff) + eo @@ -411,4 +493,5 @@ else: fo |= 3 eo = int2oct(n & 0xff) + eo + po = null @@ -414,4 +497,5 @@ po = null + while m: po = int2oct(m & 0xff) + po m >>= 8 @@ -415,4 +499,5 @@ while m: po = int2oct(m & 0xff) + po m >>= 8 + substrate = int2oct(fo) + eo + po @@ -418,2 +503,3 @@ substrate = int2oct(fo) + eo + po + return substrate, False, True @@ -419,4 +505,5 @@ return substrate, False, True + else: raise error.PyAsn1Error('Prohibited Real base %s' % b) @@ -441,6 +528,8 @@ namedType = namedTypes[idx] if namedType.isOptional and not component.isValue: - continue + if LOG: + LOG('not encoding OPTIONAL component %r' % (namedType,)) + continue if namedType.isDefaulted and component == namedType.asn1Object: @@ -445,6 +534,8 @@ if namedType.isDefaulted and component == namedType.asn1Object: - continue + if LOG: + LOG('not encoding DEFAULT component %r' % (namedType,)) + continue if self.omitEmptyOptionals: options.update(ifNotEmpty=namedType.isOptional) @@ -457,6 +548,9 @@ if wrapType.tagSet and not wrapType.isSameTypeWith(component): chunk = encodeFun(chunk, wrapType, **options) + if LOG: + LOG('wrapped open type with wrap type %r' % (wrapType,)) + substrate += chunk else: @@ -467,6 +561,7 @@ component = value[namedType.name] except KeyError: - raise error.PyAsn1Error('Component name "%s" not found in %r' % (namedType.name, value)) + raise error.PyAsn1Error('Component name "%s" not found in %r' % ( + namedType.name, value)) if namedType.isOptional and namedType.name not in value: @@ -471,5 +566,7 @@ if namedType.isOptional and namedType.name not in value: + if LOG: + LOG('not encoding OPTIONAL component %r' % (namedType,)) continue if namedType.isDefaulted and component == namedType.asn1Object: @@ -473,6 +570,8 @@ continue if namedType.isDefaulted and component == namedType.asn1Object: + if LOG: + LOG('not encoding DEFAULT component %r' % (namedType,)) continue if self.omitEmptyOptionals: @@ -486,6 +585,9 @@ if wrapType.tagSet and not wrapType.isSameTypeWith(component): chunk = encodeFun(chunk, wrapType, **options) + if LOG: + LOG('wrapped open type with wrap type %r' % (wrapType,)) + substrate += chunk return substrate, True, True