From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- python/pyasn1/doc/constraints.html | 436 +++++++++++++++++++++++++++++++++++++ 1 file changed, 436 insertions(+) create mode 100644 python/pyasn1/doc/constraints.html (limited to 'python/pyasn1/doc/constraints.html') diff --git a/python/pyasn1/doc/constraints.html b/python/pyasn1/doc/constraints.html new file mode 100644 index 000000000..53da1addf --- /dev/null +++ b/python/pyasn1/doc/constraints.html @@ -0,0 +1,436 @@ + + +PyASN1 subtype constraints + + + + +
+ + + + +
+ +

+1.4 PyASN1 subtype constraints +

+ +

+Most ASN.1 types can correspond to an infinite set of values. To adapt to +particular application's data model and needs, ASN.1 provides a mechanism +for limiting the infinite set to values, that make sense in particular case. +

+ +

+Imposing value constraints on an ASN.1 type can also be seen as creating +a subtype from its base type. +

+ +

+In pyasn1, constraints take shape of immutable objects capable +of evaluating given value against constraint-specific requirements. +Constraint object is a property of pyasn1 type. Like TagSet property, +associated with every pyasn1 type, constraints can never be modified +in place. The only way to modify pyasn1 type constraint is to associate +new constraint object to a new pyasn1 type object. +

+ +

+A handful of different flavors of constraints are defined in ASN.1. +We will discuss them one by one in the following chapters and also explain +how to combine and apply them to types. +

+ + +

+1.4.1 Single value constraint +

+ +

+This kind of constraint allows for limiting type to a finite, specified set +of values. +

+ +
+
+DialButton ::= OCTET STRING (
+  "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
+)
+
+
+ +

+Its pyasn1 implementation would look like: +

+ +
+
+>>> from pyasn1.type import constraint
+>>> c = constraint.SingleValueConstraint(
+  '0','1','2','3','4','5','6','7','8','9'
+)
+>>> c
+SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+>>> c('0')
+>>> c('A')
+Traceback (most recent call last):
+...
+pyasn1.type.error.ValueConstraintError: 
+  SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
+>>> 
+
+
+ +

+As can be seen in the snippet above, if a value violates the constraint, an +exception will be thrown. A constrainted pyasn1 type object holds a +reference to a constraint object (or their combination, as will be explained +later) and calls it for value verification. +

+ +
+
+>>> from pyasn1.type import univ, constraint
+>>> class DialButton(univ.OctetString):
+...   subtypeSpec = constraint.SingleValueConstraint(
+...       '0','1','2','3','4','5','6','7','8','9'
+...   )
+>>> DialButton('0')
+DialButton(b'0')
+>>> DialButton('A')
+Traceback (most recent call last):
+...
+pyasn1.type.error.ValueConstraintError:
+  SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) failed at: A
+>>> 
+
+
+ +

+Constrained pyasn1 value object can never hold a violating value. +

+ + +

+1.4.2 Value range constraint +

+ +

+A pair of values, compliant to a type to be constrained, denote low and upper +bounds of allowed range of values of a type. +

+ +
+
+Teenagers ::= INTEGER (13..19)
+
+
+ +

+And in pyasn1 terms: +

+ +
+
+>>> from pyasn1.type import univ, constraint
+>>> class Teenagers(univ.Integer):
+...   subtypeSpec = constraint.ValueRangeConstraint(13, 19)
+>>> Teenagers(14)
+Teenagers(14)
+>>> Teenagers(20)
+Traceback (most recent call last):
+...
+pyasn1.type.error.ValueConstraintError:
+  ValueRangeConstraint(13, 19) failed at: 20
+>>> 
+
+
+ +

+Value range constraint usually applies numeric types. +

+ + +

+1.4.3 Size constraint +

+ +

+It is sometimes convenient to set or limit the allowed size of a data item +to be sent from one application to another to manage bandwidth and memory +consumption issues. Size constraint specifies the lower and upper bounds +of the size of a valid value. +

+ +
+
+TwoBits ::= BIT STRING (SIZE (2))
+
+
+ +

+Express the same grammar in pyasn1: +

+ +
+
+>>> from pyasn1.type import univ, constraint
+>>> class TwoBits(univ.BitString):
+...   subtypeSpec = constraint.ValueSizeConstraint(2, 2)
+>>> TwoBits((1,1))
+TwoBits("'11'B")
+>>> TwoBits((1,1,0))
+Traceback (most recent call last):
+...
+pyasn1.type.error.ValueConstraintError:
+  ValueSizeConstraint(2, 2) failed at: (1, 1, 0)
+>>> 
+
+
+ +

+Size constraint can be applied to potentially massive values - bit or octet +strings, SEQUENCE OF/SET OF values. +

+ + +

+1.4.4 Alphabet constraint +

+ +

+The permitted alphabet constraint is similar to Single value constraint +but constraint applies to individual characters of a value. +

+ +
+
+MorseCode ::= PrintableString (FROM ("."|"-"|" "))
+
+
+ +

+And in pyasn1: +

+ +
+
+>>> from pyasn1.type import char, constraint
+>>> class MorseCode(char.PrintableString):
+...   subtypeSpec = constraint.PermittedAlphabetConstraint(".", "-", " ")
+>>> MorseCode("...---...")
+MorseCode('...---...')
+>>> MorseCode("?")
+Traceback (most recent call last):
+...
+pyasn1.type.error.ValueConstraintError:
+  PermittedAlphabetConstraint(".", "-", " ") failed at: "?"
+>>> 
+
+
+ +

+Current implementation does not handle ranges of characters in constraint +(FROM "A".."Z" syntax), one has to list the whole set in a range. +

+ + +

+1.4.5 Constraint combinations +

+ +

+Up to this moment, we used a single constraint per ASN.1 type. The standard, +however, allows for combining multiple individual constraints into +intersections, unions and exclusions. +

+ +

+In pyasn1 data model, all of these methods of constraint combinations are +implemented as constraint-like objects holding individual constraint (or +combination) objects. Like terminal constraint objects, combination objects +are capable to perform value verification at its set of enclosed constraints +according to the logic of particular combination. +

+ +

+Constraints intersection verification succeeds only if a value is +compliant to each constraint in a set. To begin with, the following +specification will constitute a valid telephone number: +

+ +
+
+PhoneNumber ::= NumericString (FROM ("0".."9")) (SIZE 11)
+
+
+ +

+Constraint intersection object serves the logic above: +

+ +
+
+>>> from pyasn1.type import char, constraint
+>>> class PhoneNumber(char.NumericString):
+...   subtypeSpec = constraint.ConstraintsIntersection(
+...     constraint.PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
+...     constraint.ValueSizeConstraint(11, 11)
+...   )
+>>> PhoneNumber('79039343212')
+PhoneNumber('79039343212')
+>>> PhoneNumber('?9039343212')
+Traceback (most recent call last):
+...
+pyasn1.type.error.ValueConstraintError:
+  ConstraintsIntersection(
+    PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
+      ValueSizeConstraint(11, 11)) failed at: 
+   PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9') failed at: "?039343212"
+>>> PhoneNumber('9343212')
+Traceback (most recent call last):
+...
+pyasn1.type.error.ValueConstraintError:
+  ConstraintsIntersection(
+    PermittedAlphabetConstraint('0','1','2','3','4','5','6','7','8','9'),
+      ValueSizeConstraint(11, 11)) failed at:
+  ValueSizeConstraint(10, 10) failed at: "9343212"
+>>>
+
+
+ +

+Union of constraints works by making sure that a value is compliant +to any of the constraint in a set. For instance: +

+ +
+
+CapitalOrSmall ::= IA5String (FROM ('A','B','C') | FROM ('a','b','c'))
+
+
+ +

+It's important to note, that a value must fully comply to any single +constraint in a set. In the specification above, a value of all small or +all capital letters is compliant, but a mix of small&capitals is not. +Here's its pyasn1 analogue: +

+ +
+
+>>> from pyasn1.type import char, constraint
+>>> class CapitalOrSmall(char.IA5String):
+...   subtypeSpec = constraint.ConstraintsUnion(
+...     constraint.PermittedAlphabetConstraint('A','B','C'),
+...     constraint.PermittedAlphabetConstraint('a','b','c')
+...   )
+>>> CapitalOrSmall('ABBA')
+CapitalOrSmall('ABBA')
+>>> CapitalOrSmall('abba')
+CapitalOrSmall('abba')
+>>> CapitalOrSmall('Abba')
+Traceback (most recent call last):
+...
+pyasn1.type.error.ValueConstraintError:
+  ConstraintsUnion(PermittedAlphabetConstraint('A', 'B', 'C'),
+    PermittedAlphabetConstraint('a', 'b', 'c')) failed at: failed for "Abba"
+>>>
+
+
+ +

+Finally, the exclusion constraint simply negates the logic of value +verification at a constraint. In the following example, any integer value +is allowed in a type but not zero. +

+ +
+
+NoZero ::= INTEGER (ALL EXCEPT 0)
+
+
+ +

+In pyasn1 the above definition would read: +

+ +
+
+>>> from pyasn1.type import univ, constraint
+>>> class NoZero(univ.Integer):
+...   subtypeSpec = constraint.ConstraintsExclusion(
+...     constraint.SingleValueConstraint(0)
+...   )
+>>> NoZero(1)
+NoZero(1)
+>>> NoZero(0)
+Traceback (most recent call last):
+...
+pyasn1.type.error.ValueConstraintError:
+  ConstraintsExclusion(SingleValueConstraint(0)) failed at: 0
+>>>
+
+
+ +

+The depth of such a constraints tree, built with constraint combination objects +at its nodes, has not explicit limit. Value verification is performed in a +recursive manner till a definite solution is found. +

+ + +

+1.5 Types relationships +

+ +

+In the course of data processing in an application, it is sometimes +convenient to figure out the type relationships between pyasn1 type or +value objects. Formally, two things influence pyasn1 types relationship: +tag set and subtype constraints. One pyasn1 type is considered +to be a derivative of another if their TagSet and Constraint objects are +a derivation of one another. +

+ +

+The following example illustrates the concept (we use the same tagset but +different constraints for simplicity): +

+ +
+
+>>> from pyasn1.type import univ, constraint
+>>> i1 = univ.Integer(subtypeSpec=constraint.ValueRangeConstraint(3,8))
+>>> i2 = univ.Integer(subtypeSpec=constraint.ConstraintsIntersection(
+...    constraint.ValueRangeConstraint(3,8),
+...    constraint.ValueRangeConstraint(4,7)
+... ) )
+>>> i1.isSameTypeWith(i2)
+False
+>>> i1.isSuperTypeOf(i2)
+True
+>>> i1.isSuperTypeOf(i1)
+True
+>>> i2.isSuperTypeOf(i1)
+False
+>>>
+
+
+ +

+As can be seen in the above code snippet, there are two methods of any pyasn1 +type/value object that test types for their relationship: +isSameTypeWith() and isSuperTypeOf(). The former is +self-descriptive while the latter yields true if the argument appears +to be a pyasn1 object which has tagset and constraints derived from those +of the object being called. +

+ +
+ +
+
+ + -- cgit v1.2.3