summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelie <elie>2012-07-18 16:41:14 +0000
committerelie <elie>2012-07-18 16:41:14 +0000
commitc59eb75d28ac14a0077ab743483843ee66f3de6f (patch)
treed85066572ac1ecf329330cc243c60d31d4612dd6
parentbc65170b6894f963155c88ade4d3965692d2edcf (diff)
downloadpyasn1-c59eb75d28ac14a0077ab743483843ee66f3de6f.tar.gz
* fix to Real codec exponent encoding (should be in 2's complement form)
* some more test cases added
-rw-r--r--CHANGES2
-rw-r--r--pyasn1/codec/ber/decoder.py11
-rw-r--r--pyasn1/codec/ber/encoder.py6
-rw-r--r--test/codec/ber/decoder.py26
-rw-r--r--test/codec/ber/encoder.py7
5 files changed, 41 insertions, 11 deletions
diff --git a/CHANGES b/CHANGES
index c2dabc0..6629118 100644
--- a/CHANGES
+++ b/CHANGES
@@ -18,6 +18,8 @@ Revision 0.1.4
- Package classifiers updated.
- The __init__.py's made non-empty (rumors are that they may be optimized
out by package managers).
+- Fix to Real codec exponent encoding (should be in 2's complement form),
+ some more test cases added.
- Fix in Boolean truth testing built-in methods
- Fix to substrate underrun error handling at ObjectIdentifier BER decoder
- Fix to BER Boolean decoder that allows other pre-computed
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py
index 365faeb..f63ae8c 100644
--- a/pyasn1/codec/ber/decoder.py
+++ b/pyasn1/codec/ber/decoder.py
@@ -245,18 +245,13 @@ class RealDecoder(AbstractSimpleDecoder):
if fo & 0x40: # infinite value
value = fo & 0x01 and '-inf' or 'inf'
elif fo & 0x80: # binary enoding
- if fo & 0x11 == 0:
- n = 1
- elif fo & 0x01:
- n = 2
- elif fo & 0x02:
- n = 3
- else:
+ n = (fo & 0x03) + 1
+ if n == 4:
n = oct2int(head[0])
eo, head = head[:n], head[n:]
if not eo or not head:
raise error.PyAsn1Error('Real exponent screwed')
- e = 0
+ e = oct2int(eo[0]) & 0x80 and -1 or 0
while eo: # exponent
e <<= 8
e |= oct2int(eo[0])
diff --git a/pyasn1/codec/ber/encoder.py b/pyasn1/codec/ber/encoder.py
index afcc567..181fbde 100644
--- a/pyasn1/codec/ber/encoder.py
+++ b/pyasn1/codec/ber/encoder.py
@@ -1,7 +1,7 @@
# BER encoder
from pyasn1.type import base, tag, univ, char, useful
from pyasn1.codec.ber import eoo
-from pyasn1.compat.octets import int2oct, ints2octs, null, str2octs
+from pyasn1.compat.octets import int2oct, oct2int, ints2octs, null, str2octs
from pyasn1 import debug, error
class Error(Exception): pass
@@ -203,9 +203,11 @@ class RealEncoder(AbstractItemEncoder):
m >>= 1
e += 1
eo = null
- while e:
+ 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
n = len(eo)
if n > 0xff:
raise error.PyAsn1Error('Real exponent overflow')
diff --git a/test/codec/ber/decoder.py b/test/codec/ber/decoder.py
index cfb5ee7..04d6526 100644
--- a/test/codec/ber/decoder.py
+++ b/test/codec/ber/decoder.py
@@ -188,6 +188,32 @@ class ObjectIdentifierDecoderTestCase(unittest.TestCase):
pass
else:
assert 1, 'Leading 0x80 tolarated'
+
+class RealDecoderTestCase(unittest.TestCase):
+ def testChar(self):
+ assert decoder.decode(
+ ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49))
+ ) == (univ.Real((123, 10, 11)), null)
+
+ def testBin1(self):
+ assert decoder.decode(
+ ints2octs((9, 4, 128, 245, 4, 77))
+ ) == (univ.Real((1101, 2, -11)), null)
+
+ def testBin2(self):
+ assert decoder.decode(
+ ints2octs((9, 4, 128, 11, 4, 77))
+ ) == (univ.Real((1101, 2, 11)), null)
+
+ def testPlusInf(self):
+ assert decoder.decode(
+ ints2octs((9, 1, 64))
+ ) == (univ.Real('inf'), null)
+
+ def testMinusInf(self):
+ assert decoder.decode(
+ ints2octs((9, 1, 65))
+ ) == (univ.Real('-inf'), null)
class SequenceDecoderTestCase(unittest.TestCase):
def setUp(self):
diff --git a/test/codec/ber/encoder.py b/test/codec/ber/encoder.py
index 5755cf5..af08159 100644
--- a/test/codec/ber/encoder.py
+++ b/test/codec/ber/encoder.py
@@ -134,11 +134,16 @@ class RealEncoderTestCase(unittest.TestCase):
univ.Real((123, 10, 11))
) == ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49))
- def testBin(self):
+ def testBin1(self):
assert encoder.encode(
univ.Real((1101, 2, 11))
) == ints2octs((9, 4, 128, 11, 4, 77))
+ def testBin2(self):
+ assert encoder.encode(
+ univ.Real((1101, 2, -11))
+ ) == ints2octs((9, 4, 128, 245, 4, 77))
+
def testPlusInf(self):
assert encoder.encode(univ.Real('inf')) == ints2octs((9, 1, 64))