summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Etingof <etingof@gmail.com>2017-08-22 11:14:20 +0200
committerIlya Etingof <etingof@gmail.com>2017-08-22 11:23:21 +0200
commita010010d681c3ccfb38300bbf010cadaa24830ac (patch)
treebd148c4a74b03bcc7dea750099a460b53f87d04a
parenta320d71872aa6c89621f9c584c526af0229b6071 (diff)
downloadpyasn1-git-a010010d681c3ccfb38300bbf010cadaa24830ac.tar.gz
at decoder, do not unconditionally cast substrate into bytes/str
-rw-r--r--CHANGES.rst2
-rw-r--r--pyasn1/codec/ber/decoder.py17
-rw-r--r--tests/codec/ber/test_decoder.py24
3 files changed, 37 insertions, 6 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 18072d0..e866cb8 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -3,6 +3,8 @@ Revision 0.3.3, released XX-08-2017
-----------------------------------
- Improved ASN.1 types instantiation performance
+- Improved BER/CER/DER decoder performance by not unconditionally casting
+ substrate into str/bytes.
- Fixed SetOf ordering at CER/DER encoder
- Fixed crash on conditional binascii module import
- Fix to TagSet hash value build
diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py
index 2766fe0..b7ff2e1 100644
--- a/pyasn1/codec/ber/decoder.py
+++ b/pyasn1/codec/ber/decoder.py
@@ -6,7 +6,7 @@
#
from pyasn1.type import base, tag, univ, char, useful, tagmap
from pyasn1.codec.ber import eoo
-from pyasn1.compat.octets import oct2int, octs2ints, ints2octs, ensureString, null
+from pyasn1.compat.octets import oct2int, octs2ints, ints2octs, null
from pyasn1.compat.integer import from_bytes
from pyasn1 import debug, error
@@ -783,9 +783,16 @@ for typeDecoder in tagMap.values():
typeMap[typeId] = typeDecoder
-(stDecodeTag, stDecodeLength, stGetValueDecoder, stGetValueDecoderByAsn1Spec,
- stGetValueDecoderByTag, stTryAsExplicitTag, stDecodeValue,
- stDumpRawValue, stErrorCondition, stStop) = [x for x in range(10)]
+(stDecodeTag,
+ stDecodeLength,
+ stGetValueDecoder,
+ stGetValueDecoderByAsn1Spec,
+ stGetValueDecoderByTag,
+ stTryAsExplicitTag,
+ stDecodeValue,
+ stDumpRawValue,
+ stErrorCondition,
+ stStop) = [x for x in range(10)]
class Decoder(object):
@@ -814,8 +821,6 @@ class Decoder(object):
if logger:
logger('decoder called at scope %s with state %d, working with up to %d octets of substrate: %s' % (debug.scope, state, len(substrate), debug.hexdump(substrate)))
- substrate = ensureString(substrate)
-
# Look for end-of-octets sentinel
if allowEoo and self.supportIndefLength:
if substrate[:2] == self.__eooSentinel:
diff --git a/tests/codec/ber/test_decoder.py b/tests/codec/ber/test_decoder.py
index 03bfcab..0a53bcf 100644
--- a/tests/codec/ber/test_decoder.py
+++ b/tests/codec/ber/test_decoder.py
@@ -840,6 +840,30 @@ class EndOfOctetsTestCase(unittest.TestCase):
assert 0, 'end-of-contents octets accepted with unexpected data'
+class NonStringDecoderTestCase(unittest.TestCase):
+ def setUp(self):
+ self.s = univ.Sequence(
+ componentType=namedtype.NamedTypes(
+ namedtype.NamedType('place-holder', univ.Null(null)),
+ namedtype.NamedType('first-name', univ.OctetString(null)),
+ namedtype.NamedType('age', univ.Integer(33))
+ )
+ )
+ self.s.setComponentByPosition(0, univ.Null(null))
+ self.s.setComponentByPosition(1, univ.OctetString('quick brown'))
+ self.s.setComponentByPosition(2, univ.Integer(1))
+
+ self.substrate = ints2octs([48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1])
+
+ def testOctetString(self):
+ s, _ = decoder.decode(univ.OctetString(self.substrate), asn1Spec=self.s)
+ assert self.s == s
+
+ def testAny(self):
+ s, _ = decoder.decode(univ.Any(self.substrate), asn1Spec=self.s)
+ assert self.s == s
+
+
suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__])
if __name__ == '__main__':