summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelie <elie>2013-10-31 21:28:57 +0000
committerelie <elie>2013-10-31 21:28:57 +0000
commit825e9c706e9f79bc0034bcc755096b5c8abd4515 (patch)
tree95b938cee416c0bc6a7c86d0f65693b06f939658
parent2e86ae96612d7a3b4ca94524c7c25c7b6578af0f (diff)
downloadpyasn1-825e9c706e9f79bc0034bcc755096b5c8abd4515.tar.gz
ObjectIdentifier codec fixed to work properly with arc 0 and arc 2 values
-rw-r--r--CHANGES1
-rw-r--r--pyasn1/codec/ber/decoder.py16
-rw-r--r--pyasn1/codec/ber/encoder.py18
-rw-r--r--test/codec/ber/test_decoder.py14
-rw-r--r--test/codec/ber/test_encoder.py19
5 files changed, 55 insertions, 13 deletions
diff --git a/CHANGES b/CHANGES
index 43374eb..414efc5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,7 @@
Revision 0.1.8
--------------
+- ObjectIdentifier codec fixed to work properly with arc 0 and arc 2 values.
- Unicode initializer support added to OctetString type and derivatives.
- Fix to SEQUENCE and SET types to give them their private componentTypes
collection (which is a NamedTypes object) so that they won't collide in
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py
index 2c6896f..1530a54 100644
--- a/pyasn1/codec/ber/decoder.py
+++ b/pyasn1/codec/ber/decoder.py
@@ -216,14 +216,24 @@ class ObjectIdentifierDecoder(AbstractSimpleDecoder):
if not head:
raise error.PyAsn1Error('Empty substrate')
- # Get the first subid
+ # Decode the first octet
+ index = 1
subId = oct2int(head[0])
- oid = divmod(subId, 40)
+ if 0 <= subId <= 39:
+ oid = 0, subId
+ elif 40 <= subId <= 79:
+ oid = 1, subId - 40
+ elif subId >= 80:
+ oid = 2,
+ index = 0
+ else:
+ raise error.PyAsn1Error('Malformed first OID octet: %s' % subId)
- index = 1
substrateLen = len(head)
while index < substrateLen:
subId = oct2int(head[index])
+ if index == 0:
+ subId -= 80
index = index + 1
if subId == 128:
# ASN.1 spec forbids leading zeros (0x80) in sub-ID OID
diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py
index cfb59a8..c4db49e 100644
--- a/pyasn1/codec/ber/encoder.py
+++ b/pyasn1/codec/ber/encoder.py
@@ -166,13 +166,20 @@ class ObjectIdentifierEncoder(AbstractItemEncoder):
if len(oid) < 2:
raise error.PyAsn1Error('Short OID %s' % (value,))
+ index = 2
+
# Build the first twos
- if oid[0] > 6 or oid[1] > 39 or oid[0] == 6 and oid[1] > 15:
+ if oid[0] == 0 and 0 <= oid[1] <= 39:
+ octets = (oid[1],)
+ elif oid[0] == 1 and 0 <= oid[1] <= 39:
+ octets = (oid[1] + 40,)
+ elif oid[0] == 2:
+ octets = ()
+ index = 1
+ else:
raise error.PyAsn1Error(
'Initial sub-ID overflow %s in OID %s' % (oid[:2], value)
)
- octets = (oid[0] * 40 + oid[1],)
- index = 2
# Cycle through subids
for subid in oid[index:]:
@@ -192,7 +199,10 @@ class ObjectIdentifierEncoder(AbstractItemEncoder):
subid = subid >> 7
# Add packed Sub-Object ID to resulted Object ID
octets += res
-
+
+ if index == 1:
+ octets = (octets[0]+80,) + octets[1:]
+
return ints2octs(octets), 0
class RealEncoder(AbstractItemEncoder):
diff --git a/test/codec/ber/test_decoder.py b/test/codec/ber/test_decoder.py
index b581bc6..294e0ce 100644
--- a/test/codec/ber/test_decoder.py
+++ b/test/codec/ber/test_decoder.py
@@ -187,13 +187,19 @@ class ObjectIdentifierDecoderTestCase(unittest.TestCase):
def testEdges1(self):
assert decoder.decode(
- ints2octs((6, 1, 255))
- ) == ((6,15), null)
+ ints2octs((6, 1, 39))
+ ) == ((0,39), null)
def testEdges2(self):
assert decoder.decode(
- ints2octs((6, 1, 239))
- ) == ((5,39), null)
+ ints2octs((6, 1, 79))
+ ) == ((1,39), null)
+
+ def testEdges3(self):
+ assert decoder.decode(
+ ints2octs((6, 5, 223, 255, 255, 255, 127))
+ ) == ((2,0xffffffff), null)
+
def testEdges3(self):
assert decoder.decode(
diff --git a/test/codec/ber/test_encoder.py b/test/codec/ber/test_encoder.py
index edf43b0..3a0a1b2 100644
--- a/test/codec/ber/test_encoder.py
+++ b/test/codec/ber/test_encoder.py
@@ -132,10 +132,25 @@ class NullEncoderTestCase(unittest.TestCase):
assert encoder.encode(univ.Null('')) == ints2octs((5, 0))
class ObjectIdentifierEncoderTestCase(unittest.TestCase):
- def testNull(self):
+ def testOne(self):
assert encoder.encode(
univ.ObjectIdentifier((1,3,6,0,0xffffe))
- ) == ints2octs((6, 6, 43, 6, 0, 191, 255, 126))
+ ) == ints2octs((6, 6, 43, 6, 0, 191, 255, 126))
+
+ def testEdge1(self):
+ assert encoder.encode(
+ univ.ObjectIdentifier((0,39))
+ ) == ints2octs((6,1,39))
+
+ def testEdge2(self):
+ assert encoder.encode(
+ univ.ObjectIdentifier((1,39))
+ ) == ints2octs((6,1,79))
+
+ def testEdge3(self):
+ assert encoder.encode(
+ univ.ObjectIdentifier((2,0xffffffff))
+ ) == ints2octs((6, 5, 223, 255, 255, 255, 127))
class RealEncoderTestCase(unittest.TestCase):
def testChar(self):