laforge has submitted this change. ( https://gerrit.osmocom.org/c/pysim/+/28185 )
Change subject: ts_102_221: The BTLV IEs FILE SIZE and TOTAL FILE SIZE have a min length ......................................................................
ts_102_221: The BTLV IEs FILE SIZE and TOTAL FILE SIZE have a min length
The TLV IEs FILE SIZE and TOTAL FILE SIZE have a minimum length of 2 byte. Even when the length is in the single digit range two bytes must be used. See also: ETSI TS 102 221, section 11.1.1.4.1 and 11.1.1.4.2
Change-Id: Ief113ce8fe3bcae2c9fb2ff4138df9ccf98d26ff --- M pySim/construct.py M pySim/ts_102_221.py 2 files changed, 16 insertions(+), 8 deletions(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved
diff --git a/pySim/construct.py b/pySim/construct.py index fcbadd8..4910a7f 100644 --- a/pySim/construct.py +++ b/pySim/construct.py @@ -208,10 +208,11 @@
class GreedyInteger(Construct): """A variable-length integer implementation, think of combining GrredyBytes with BytesInteger.""" - def __init__(self, signed=False, swapped=False): + def __init__(self, signed=False, swapped=False, minlen=0): super().__init__() self.signed = signed self.swapped = swapped + self.minlen = minlen
def _parse(self, stream, context, path): data = stream_read_entire(stream, path) @@ -222,23 +223,30 @@ except ValueError as e: raise IntegerError(str(e), path=path)
- def __bytes_required(self, i): + def __bytes_required(self, i, minlen=0): if self.signed: raise NotImplementedError("FIXME: Implement support for encoding signed integer") + + # compute how many bytes we need nbytes = 1 while True: i = i >> 8 if i == 0: - return nbytes + break else: nbytes = nbytes + 1 - # this should never happen, above loop must return eventually... - raise IntegerError(f"value {i} is out of range") + + # round up to the minimum number + # of bytes we anticipate + if nbytes < minlen: + nbytes = minlen + + return nbytes
def _build(self, obj, stream, context, path): if not isinstance(obj, integertypes): raise IntegerError(f"value {obj} is not an integer", path=path) - length = self.__bytes_required(obj) + length = self.__bytes_required(obj, self.minlen) try: data = integer2bytes(obj, length, self.signed) except ValueError as e: diff --git a/pySim/ts_102_221.py b/pySim/ts_102_221.py index e7aff97..08e836c 100644 --- a/pySim/ts_102_221.py +++ b/pySim/ts_102_221.py @@ -80,11 +80,11 @@
# ETSI TS 102 221 11.1.1.4.2 class FileSize(BER_TLV_IE, tag=0x80): - _construct = GreedyInteger() + _construct = GreedyInteger(minlen=2)
# ETSI TS 102 221 11.1.1.4.2 class TotalFileSize(BER_TLV_IE, tag=0x81): - _construct = GreedyInteger() + _construct = GreedyInteger(minlen=2)
# ETSI TS 102 221 11.1.1.4.3 class FileDescriptor(BER_TLV_IE, tag=0x82):