From 0c8ade519224c4058dbc5ae60441269226a5a209 Mon Sep 17 00:00:00 2001 From: Christian Van Wambeke Date: Wed, 27 Jun 2018 10:26:39 +0200 Subject: [PATCH] fix '&&' in xml launchCommand attribute --- src/logger.py | 32 ++++++++++++++++++++++++-------- src/salomeTools.py | 1 + src/xmlManager.py | 36 ++++++++++++++++++++++++++++++++++-- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/logger.py b/src/logger.py index 310b157..f50ae77 100755 --- a/src/logger.py +++ b/src/logger.py @@ -25,6 +25,7 @@ import os import datetime import re import tempfile +import shutil import src import printcolors @@ -159,12 +160,9 @@ class Logger(object): ("sat command ...") """ xmlLinks = self.xmlFile.xmlroot.find("Links") - src.xmlManager.add_simple_node(xmlLinks, - "link", - text = log_file_name, - attrib = {"command" : command_name, - "passed" : command_res, - "launchedCommand" : full_launched_command}) + flc = src.xmlManager.escapeSequence(full_launched_command) + att = {"command" : command_name, "passed" : command_res, "launchedCommand" : flc} + src.xmlManager.add_simple_node(xmlLinks, "link", text = log_file_name, attrib = att) def write(self, message, level=None, screenOnly=False): """\ @@ -254,10 +252,28 @@ class Logger(object): # Call the method to write the xml file on the hard drive self.xmlFile.write_tree(stylesheet = "command.xsl") + + # so unconditionnaly copy stylesheet file(s) + xslDir = os.path.join(self.config.VARS.srcDir, 'xsl') + xslCommand = "command.xsl" + # xslHat = "hat.xsl" # have to be completed (one time at end) + xsltest = "test.xsl" + imgLogo = "LOGO-SAT.png" + files_to_copy = [xslCommand, xsltest, imgLogo] + + logDir = src.get_log_path(self.config) + # copy the stylesheets in the log directory as soon as possible here + # because referenced in self.xmlFile.write_tree above + # OP We use copy instead of copy2 to update the creation date + # So we can clean the LOGS directories easily + for f in files_to_copy: + f_init = os.path.join(xslDir, f) + f_target = os.path.join(logDir, f) + if not os.path.isfile(f_target): # do not overrride + shutil.copy(f_init, logDir) # Dump the config in a pyconf file in the log directory - logDir = src.get_log_path(self.config) - dumpedPyconfFileName = (self.config.VARS.datehour + dumpedPyconfFileName = (self.config.VARS.datehour + "_" + self.config.VARS.command + ".pyconf") diff --git a/src/salomeTools.py b/src/salomeTools.py index 139e3cc..ef3857e 100755 --- a/src/salomeTools.py +++ b/src/salomeTools.py @@ -515,6 +515,7 @@ class Sat(object): options_launched, __nameCmd__, ' '.join(argv_0)]) + # TODO may be no need as call escapeSequence xml launchedCommand = launchedCommand.replace('"', "'") # Add a link to the parent command diff --git a/src/xmlManager.py b/src/xmlManager.py index ca8ec61..d619980 100644 --- a/src/xmlManager.py +++ b/src/xmlManager.py @@ -44,8 +44,40 @@ class XmlLogFile(object): src.ensure_path_exists(os.path.dirname(filePath)) # Initialize the field that contain the xml in memory self.xmlroot = etree.Element(rootname, attrib = attrib) - - def write_tree(self, stylesheet=None, file_path = None): + + def escapeSequence(self, aStr): + """ + See xml specification: + The ampersand character(&) and the left angle bracket(<) MUST NOT appear in their + literal form, except when used as markup delimiters, or within a comment, a processing + instruction, or a CDATA section. + If they are needed elsewhere, they MUST be escaped using either numeric character references + or the strings '&' and '<' respectively. + The right angle bracket(>) may be + represented using the string '>', and MUST, + for compatibility, be escaped using either '>' or a character reference + when it appears in the string " ]]> " in content, + when that string is not marking the end of a CDATA section. + You can use these escape sequences: + < (less - than) as < or < + > (greater - than) as > or > + & (ampersand) as & + ' (apostrophe or single quote) as ' + " (double-quote) as " + """ + replaces = [ ('&', '&'), + ('>', '>'), + ('<', '<'), + ("'", '''), + ('"', '"'), + ] + res = aStr + for ini, fin in replaces: # order matters + res = res.replace(ini, fin) + return res + + +def write_tree(self, stylesheet=None, file_path = None): '''Write the xml tree in the log file path. Add the stylesheet if asked. :param stylesheet str: The stylesheet to apply to the xml file -- 2.39.2