From ac34dcc149ebd41d81b6954b805f9d09f3e56a8b Mon Sep 17 00:00:00 2001 From: Philipp Maier Date: Thu, 1 Apr 2021 17:19:05 +0200 Subject: [PATCH] pySim-shell: fix and improve file system exporter The file system exporter function export() selects the exported EF from inside a try block. It also selects the parent DF again when leaving the try block. If an exception ocurrs during select this is fine, but if it happens during read it leaves the EF selected which makes messes up the recursive filesystem walk. There are also minor inconsistancies with the exception strings and the path displayed in the execption strings Related: OS#4963 Change-Id: Ie9b1712b37e5b39e9016497185510a2a45c4ca6c --- pySim-shell.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/pySim-shell.py b/pySim-shell.py index 2ac0b265..3c56f51f 100755 --- a/pySim-shell.py +++ b/pySim-shell.py @@ -277,28 +277,33 @@ class Iso7816Commands(CommandSet): self.walk() def export(self, filename, context): + """ Select and export a single file """ context['COUNT'] += 1 - path_list = self._cmd.rs.selected_file.fully_qualified_path(True) - path_list_fid = self._cmd.rs.selected_file.fully_qualified_path(False) + df = self._cmd.rs.selected_file + + if not isinstance(df, CardDF): + raise RuntimeError("currently selected file %s is not a DF or ADF" % str(df)) + + df_path_list = df.fully_qualified_path(True) + df_path_list_fid = df.fully_qualified_path(False) self._cmd.poutput("#" * 80) - file_str = '/'.join(path_list) + "/" + str(filename) + " " * 80 + file_str = '/'.join(df_path_list) + "/" + str(filename) + " " * 80 self._cmd.poutput("# " + file_str[0:77] + "#") self._cmd.poutput("#" * 80) - self._cmd.poutput("# directory: %s (%s)" % ('/'.join(path_list), '/'.join(path_list_fid))) + self._cmd.poutput("# directory: %s (%s)" % ('/'.join(df_path_list), '/'.join(df_path_list_fid))) try: fcp_dec = self._cmd.rs.select(filename, self._cmd) - path_list = self._cmd.rs.selected_file.fully_qualified_path(True) - path_list_fid = self._cmd.rs.selected_file.fully_qualified_path(False) - self._cmd.poutput("# file: %s (%s)" % (path_list[-1], path_list_fid[-1])) + self._cmd.poutput("# file: %s (%s)" % (self._cmd.rs.selected_file.name, self._cmd.rs.selected_file.fid)) fd = fcp_dec['file_descriptor'] structure = fd['structure'] self._cmd.poutput("# structure: %s" % str(structure)) - for f in path_list: + for f in df_path_list: self._cmd.poutput("select " + str(f)) + self._cmd.poutput("select " + self._cmd.rs.selected_file.name) if structure == 'transparent': result = self._cmd.rs.read_binary() @@ -308,13 +313,18 @@ class Iso7816Commands(CommandSet): for r in range(1, num_of_rec + 1): result = self._cmd.rs.read_record(r) self._cmd.poutput("update_record %d %s" % (r, str(result[0]))) - fcp_dec = self._cmd.rs.select("..", self._cmd) except Exception as e: - bad_file_str = '/'.join(path_list) + "/" + str(filename) + ", " + str(e) + bad_file_str = '/'.join(df_path_list) + "/" + str(filename) + ", " + str(e) self._cmd.poutput("# bad file: %s" % bad_file_str) context['ERR'] += 1 context['BAD'].append(bad_file_str) + # When reading the file is done, make sure the parent file is + # selected again. This will be the usual case, however we need + # to check before since we must not select the same DF twice + if df != self._cmd.rs.selected_file: + self._cmd.rs.select(df.fid or df.aid, self._cmd) + self._cmd.poutput("#") export_parser = argparse.ArgumentParser()