summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelie <elie>2013-12-02 12:38:20 +0000
committerelie <elie>2013-12-02 12:38:20 +0000
commit4ca0e11991c5045e3e70b164ed9ede979028853a (patch)
treeba85fd9fdb80d25fd3c863818003872a5cec205e
parent6ab22c92a5833238047749ff7ce20f3f507637c1 (diff)
downloadpyasn1-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--CHANGES3
-rw-r--r--pyasn1/type/base.py22
-rw-r--r--pyasn1/type/univ.py85
-rw-r--r--test/type/test_univ.py75
4 files changed, 152 insertions, 33 deletions
diff --git a/CHANGES b/CHANGES
index 083d729..38ccf7c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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):