diff options
author | elie <elie> | 2013-12-02 12:38:20 +0000 |
---|---|---|
committer | elie <elie> | 2013-12-02 12:38:20 +0000 |
commit | 4ca0e11991c5045e3e70b164ed9ede979028853a (patch) | |
tree | ba85fd9fdb80d25fd3c863818003872a5cec205e | |
parent | 6ab22c92a5833238047749ff7ce20f3f507637c1 (diff) | |
download | pyasn1-4ca0e11991c5045e3e70b164ed9ede979028853a.tar.gz |
the setComponentBy*() methods of all CONSTRUCTED objects now accept optional
exactTypes, matchTags and matchConstraints flags to give apps finer control
on when not to perform relevant data consistency checks
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | pyasn1/type/base.py | 22 | ||||
-rw-r--r-- | pyasn1/type/univ.py | 85 | ||||
-rw-r--r-- | test/type/test_univ.py | 75 |
4 files changed, 152 insertions, 33 deletions
@@ -18,6 +18,9 @@ Revision 0.1.8 - When comparing ASN.1 types, by-tag and/or by-constraints matching can now be performed with the isSuperTypeOf()/isSameTypeWith() optional flags. +- The setComponentBy*() methods of all CONSTRUCTED objects now accept optional + exactTypes, matchTags and matchConstraints flags to give apps finer control + on when not to perform relevant data consistency checks. - Fix to NamedType.__repr__() to work properly. - Fixes to __repr__() implementation of many built-in ASN.1 types to take into account all of their initializers such as tagSet, subtypeSpec etc. diff --git a/pyasn1/type/base.py b/pyasn1/type/base.py index 2380fb0..817aeb6 100644 --- a/pyasn1/type/base.py +++ b/pyasn1/type/base.py @@ -38,18 +38,18 @@ class Asn1ItemBase(Asn1Item): def getEffectiveTagSet(self): return self._tagSet # used by untagged types def getTagMap(self): return tagmap.TagMap({self._tagSet: self}) - def isSameTypeWith(self, other, ignoreTags=False, ignoreConstraints=False): + def isSameTypeWith(self, other, matchTags=True, matchConstraints=True): return self is other or \ - (ignoreTags or \ + (not matchTags or \ self._tagSet == other.getTagSet()) and \ - (ignoreConstraints or \ + (not matchConstraints or \ self._subtypeSpec==other.getSubtypeSpec()) - def isSuperTypeOf(self, other, ignoreTags=False, ignoreConstraints=False): + def isSuperTypeOf(self, other, matchTags=True, matchConstraints=True): """Returns true if argument is a ASN1 subtype of ourselves""" - return (ignoreTags or \ + return (not matchTags or \ self._tagSet.isSuperTagSetOf(other.getTagSet())) and \ - (ignoreConstraints or \ + (not matchConstraints or \ (self._subtypeSpec.isSuperTypeOf(other.getSubtypeSpec()))) class NoValue: @@ -244,13 +244,19 @@ class AbstractConstructedAsn1Item(Asn1ItemBase): self._cloneComponentValues(r, cloneValueFlag) return r - def _verifyComponent(self, idx, value): pass + def _verifyComponent(self, idx, value, exactTypes=False, + matchTags=True, matchConstraints=True): + pass def verifySizeSpec(self): self._sizeSpec(self) def getComponentByPosition(self, idx): raise error.PyAsn1Error('Method not implemented') - def setComponentByPosition(self, idx, value, verifyConstraints=True): + def setComponentByPosition(self, idx, value, + verifyConstraints=True, + exactTypes=False, + matchTags=True, + matchConstraints=True): raise error.PyAsn1Error('Method not implemented') def getComponentType(self): return self._componentType diff --git a/pyasn1/type/univ.py b/pyasn1/type/univ.py index 29f99fd..e118468 100644 --- a/pyasn1/type/univ.py +++ b/pyasn1/type/univ.py @@ -79,7 +79,7 @@ class Integer(base.AbstractSimpleAsn1Item): return int(value) except: raise error.PyAsn1Error( - 'Can\'t coerce %s into integer: %s' % (value, sys.exc_info()[1]) + 'Can\'t coerce %r into integer: %s' % (value, sys.exc_info()[1]) ) r = self.__namedValues.getValue(value) if r is not None: @@ -88,7 +88,7 @@ class Integer(base.AbstractSimpleAsn1Item): return int(value) except: raise error.PyAsn1Error( - 'Can\'t coerce %s into integer: %s' % (value, sys.exc_info()[1]) + 'Can\'t coerce %r into integer: %s' % (value, sys.exc_info()[1]) ) def prettyOut(self, value): @@ -689,13 +689,21 @@ class SetOf(base.AbstractConstructedAsn1Item): myClone.setComponentByPosition(idx, c.clone()) idx = idx + 1 - def _verifyComponent(self, idx, value): - if self._componentType is not None and \ - not self._componentType.isSuperTypeOf(value): - raise error.PyAsn1Error('Component type error %s' % (value,)) + def _verifyComponent(self, idx, value, exactTypes=False, + matchTags=True, matchConstraints=True): + if self._componentType is not None: + f = exactTypes and \ + self._componentType.isSameTypeWith or \ + self._componentType.isSuperTypeOf + if not f(value, matchTags, matchConstraints): + raise error.PyAsn1Error('Component type error %r' % (value,)) def getComponentByPosition(self, idx): return self._componentValues[idx] - def setComponentByPosition(self, idx, value=None, verifyConstraints=True): + def setComponentByPosition(self, idx, value=None, + verifyConstraints=True, + exactTypes=False, + matchTags=True, + matchConstraints=True): l = len(self._componentValues) if idx >= l: self._componentValues = self._componentValues + (idx-l+1)*[None] @@ -715,7 +723,10 @@ class SetOf(base.AbstractConstructedAsn1Item): raise error.PyAsn1Error('Instance value required') if verifyConstraints: if self._componentType is not None: - self._verifyComponent(idx, value) + self._verifyComponent(idx, value, + exactTypes=exactTypes, + matchTags=matchTags, + matchConstraints=matchConstraints) self._verifySubtypeSpec(value, idx) if self._componentValues[idx] is None: self._componentValuesSet = self._componentValuesSet + 1 @@ -779,24 +790,30 @@ class SequenceAndSetBase(base.AbstractConstructedAsn1Item): myClone.setComponentByPosition(idx, c.clone()) idx = idx + 1 - def _verifyComponent(self, idx, value): + def _verifyComponent(self, idx, value, exactTypes=False, + matchTags=True, matchConstraints=True): if idx >= self._componentTypeLen: raise error.PyAsn1Error( 'Component type error out of range' ) t = self._componentType[idx].getType() - if not t.isSuperTypeOf(value): + f = exactTypes and t.isSameTypeWith or t.isSuperTypeOf + if not f(value, matchTags, matchConstraints): raise error.PyAsn1Error('Component type error %r vs %r' % (t, value)) def getComponentByName(self, name): return self.getComponentByPosition( self._componentType.getPositionByName(name) ) - def setComponentByName(self, name, value=None, verifyConstraints=True): + def setComponentByName(self, name, value=None, + verifyConstraints=True, + exactTypes=False, + matchTags=True, + matchConstraints=True): return self.setComponentByPosition( self._componentType.getPositionByName(name), value, - verifyConstraints - ) + verifyConstraints, exactTypes, matchTags, matchConstraints + ) def getComponentByPosition(self, idx): try: @@ -805,7 +822,11 @@ class SequenceAndSetBase(base.AbstractConstructedAsn1Item): if idx < self._componentTypeLen: return raise - def setComponentByPosition(self, idx, value=None, verifyConstraints=True): + def setComponentByPosition(self, idx, value=None, + verifyConstraints=True, + exactTypes=False, + matchTags=True, + matchConstraints=True): l = len(self._componentValues) if idx >= l: self._componentValues = self._componentValues + (idx-l+1)*[None] @@ -822,7 +843,10 @@ class SequenceAndSetBase(base.AbstractConstructedAsn1Item): raise error.PyAsn1Error('Instance value required') if verifyConstraints: if self._componentTypeLen: - self._verifyComponent(idx, value) + self._verifyComponent(idx, value, + exactTypes=exactTypes, + matchTags=matchTags, + matchConstraints=matchConstraints) self._verifySubtypeSpec(value, idx) if self._componentValues[idx] is None: self._componentValuesSet = self._componentValuesSet + 1 @@ -908,23 +932,29 @@ class Set(SequenceAndSetBase): return c def setComponentByType(self, tagSet, value=None, innerFlag=0, - verifyConstraints=True): + verifyConstraints=True, + exactTypes=False, + matchTags=True, + matchConstraints=True): idx = self._componentType.getPositionByType(tagSet) t = self._componentType.getTypeByPosition(idx) if innerFlag: # set inner component by inner tagSet if t.getTagSet(): return self.setComponentByPosition( - idx, value, verifyConstraints - ) + idx, value, verifyConstraints, + exactTypes, matchTags, matchConstraints + ) else: t = self.setComponentByPosition(idx).getComponentByPosition(idx) return t.setComponentByType( - tagSet, value, innerFlag, verifyConstraints - ) + tagSet, value, innerFlag, + verifyConstraints, exactTypes, matchTags, matchConstraints + ) else: # set outer component by inner tagSet return self.setComponentByPosition( - idx, value, verifyConstraints - ) + idx, value, + verifyConstraints, exactTypes, matchTags, matchConstraints + ) def getComponentTagMap(self): if self._componentType: @@ -996,7 +1026,11 @@ class Choice(Set): else: myClone.setComponentByType(tagSet, c.clone()) - def setComponentByPosition(self, idx, value=None, verifyConstraints=True): + def setComponentByPosition(self, idx, value=None, + verifyConstraints=True, + exactTypes=False, + matchTags=True, + matchConstraints=True): l = len(self._componentValues) if idx >= l: self._componentValues = self._componentValues + (idx-l+1)*[None] @@ -1014,7 +1048,10 @@ class Choice(Set): ) if verifyConstraints: if self._componentTypeLen: - self._verifyComponent(idx, value) + self._verifyComponent(idx, value, + exactTypes=exactTypes, + matchTags=matchTags, + matchConstraints=matchConstraints) self._verifySubtypeSpec(value, idx) self._componentValues[idx] = value self._currentIdx = idx diff --git a/test/type/test_univ.py b/test/type/test_univ.py index 37197f7..417c18d 100644 --- a/test/type/test_univ.py +++ b/test/type/test_univ.py @@ -286,9 +286,48 @@ class SequenceOf(unittest.TestCase): try: s.setComponentByPosition(1, univ.OctetString('Abc')) except: - pass + try: + s.setComponentByPosition(1, univ.OctetString('Abc'), + verifyConstraints=False) + except: + assert 0, 'constraint failes with verifyConstraints=True' else: assert 0, 'constraint fails' + def testComponentTagsMatching(self): + s = self.s1.clone() + o = univ.OctetString('abc').subtype(explicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 12)) + try: + s.setComponentByPosition(0, o) + except: + assert 0, 'inner supertype tag not allowed with exactTypes=False' + try: + s.setComponentByPosition(0, o, exactTypes=True) + except: + try: + s.setComponentByPosition(0, o, exactTypes=True, + matchTags=False) + except: + assert 0, 'inner supertype tag denied with exactTypes=True & matchTags=False' + else: + assert 0, 'inner supertype tag allowed with exactTypes=True' + def testComponentConstraintsMatching(self): + s = self.s1.clone() + o = univ.OctetString().subtype(subtypeSpec=constraint.ConstraintsUnion(constraint.SingleValueConstraint(str2octs('cba')))) + try: + s.setComponentByPosition(0, o.clone('cba')) + except: + assert 0, 'inner supertype constraint not allowed with exactTypes=False' + try: + s.setComponentByPosition(0, o.clone('cba'), exactTypes=True) + except: + try: + s.setComponentByPosition(0, o.clone('cba'), + exactTypes=True, + matchConstraints=False) + except: + assert 0, 'inner supertype constraint denied with exactTypes=True & matchConstriaints=False' + else: + assert 0, 'inner supertype constraint allowed with exactTypes=True' def testSizeSpec(self): s = self.s1.clone(sizeSpec=constraint.ConstraintsUnion( constraint.ValueSizeConstraint(1,1) @@ -378,6 +417,40 @@ class Sequence(unittest.TestCase): assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0) assert s.getComponentByPosition(1) == self.s1.getComponentByPosition(1) assert s.getComponentByPosition(2) == self.s1.getComponentByPosition(2) + def testComponentTagsMatching(self): + s = self.s1.clone() + o = univ.OctetString('abc').subtype(explicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 12)) + try: + s.setComponentByName('name', o) + except: + assert 0, 'inner supertype tag not allowed with exactTypes=False' + try: + s.setComponentByName('name', o, exactTypes=True) + except: + try: + s.setComponentByName('name', o, exactTypes=True, + matchTags=False) + except: + assert 0, 'inner supertype tag denied with exactTypes=True & matchTags=False' + else: + assert 0, 'inner supertype tag allowed with exactTypes=True' + def testComponentConstraintsMatching(self): + s = self.s1.clone() + o = univ.OctetString().subtype(subtypeSpec=constraint.ConstraintsUnion(constraint.SingleValueConstraint(str2octs('cba')))) + try: + s.setComponentByName('name', o.clone('cba')) + except: + assert 0, 'inner supertype constraint not allowed with exactTypes=False' + try: + s.setComponentByName('name', o.clone('cba'), exactTypes=True) + except: + try: + s.setComponentByName('name', o.clone('cba'), + exactTypes=True, matchConstraints=False) + except: + assert 0, 'inner supertype constraint denied with exactTypes=True & matchConstriaints=False' + else: + assert 0, 'inner supertype constraint allowed with exactTypes=True' class SetOf(unittest.TestCase): def setUp(self): |