laforge has submitted this change. (
https://gerrit.osmocom.org/c/pysim/+/41228?usp=email )
Change subject: runtime: check record/file size before write
......................................................................
runtime: check record/file size before write
When writing data to a transparent or linear fixed (record oriented)
and the data to write exceeds the record/file size, then the UICC will
respond with an error "6700: Checking errors - Wrong length"
In particular when the data is supplied as a JSON object and not as a
hex string, it may not be immediately obvious to the average user what
the problem actually is.
Let's check the record/file size before writing the data and raise an
exception in case the data excieeds the record/file size. Let's also
print an informative string message in case the data length is less
than the record/file size to make the user aware of unwritten bytes
at the end of a record/file.
Related: OS#6864
Change-Id: I7fa717d803ae79398d2c5daf92a7336be660c5ad
---
M pySim/runtime.py
1 file changed, 43 insertions(+), 0 deletions(-)
Approvals:
Jenkins Builder: Verified
laforge: Looks good to me, approved
diff --git a/pySim/runtime.py b/pySim/runtime.py
index ab21912..597323f 100644
--- a/pySim/runtime.py
+++ b/pySim/runtime.py
@@ -514,6 +514,47 @@
dec_data = self.selected_file.decode_hex(data)
return (dec_data, sw)
+ def __get_writeable_size(self):
+ """ Determine the writable size (file or record) using the cached FCP
parameters of the currently selected
+ file. Return None in case the writeable size cannot be determined
(no FCP available, FCP lacks size
+ information).
+ """
+ fcp = self.selected_file_fcp
+ if not fcp:
+ return None
+
+ structure = fcp.get('file_descriptor', {}).get('file_descriptor_byte',
{}).get('structure')
+ if not structure:
+ return None
+
+ if structure == 'transparent':
+ return fcp.get('file_size')
+ elif structure == 'linear_fixed':
+ return fcp.get('file_descriptor', {}).get('record_len')
+ else:
+ return None
+
+ def __check_writeable_size(self, data_len):
+ """ Guard against unsuccessful writes caused by attempts to write data
that exceeds the file limits. """
+
+ writeable_size = self.__get_writeable_size()
+ if not writeable_size:
+ return
+
+ if isinstance(self.selected_file, TransparentEF):
+ writeable_name = "file"
+ elif isinstance(self.selected_file, LinFixedEF):
+ writeable_name = "record"
+ else:
+ writeable_name = "object"
+
+ if data_len > writeable_size:
+ raise TypeError("Data length (%u) exceeds %s size (%u) by %u
bytes" %
+ (data_len, writeable_name, writeable_size,
data_len - writeable_size))
+ elif data_len < writeable_size:
+ log.warn("Data length (%u) less than %s size (%u), leaving %u
unwritten bytes at the end of the %s" %
+ (data_len, writeable_name, writeable_size, writeable_size
- data_len, writeable_name))
+
def update_binary(self, data_hex: str, offset: int = 0):
"""Update transparent EF binary data.
@@ -524,6 +565,7 @@
if not isinstance(self.selected_file, TransparentEF):
raise TypeError("Only works with TransparentEF, but %s is %s" %
(self.selected_file,
self.selected_file.__class__.__mro__))
+ self.__check_writeable_size(len(data_hex) // 2 + offset)
return self.scc.update_binary(self.selected_file.fid, data_hex,
offset, conserve=self.rs.conserve_write)
def update_binary_dec(self, data: dict):
@@ -571,6 +613,7 @@
if not isinstance(self.selected_file, LinFixedEF):
raise TypeError("Only works with Linear Fixed EF, but %s is %s" %
(self.selected_file,
self.selected_file.__class__.__mro__))
+ self.__check_writeable_size(len(data_hex) // 2)
return self.scc.update_record(self.selected_file.fid, rec_nr, data_hex,
conserve=self.rs.conserve_write,
leftpad=self.selected_file.leftpad)
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/41228?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I7fa717d803ae79398d2c5daf92a7336be660c5ad
Gerrit-Change-Number: 41228
Gerrit-PatchSet: 4
Gerrit-Owner: dexter <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <[email protected]>