Salome HOME
fix '&&' in xml launchCommand attribute
authorChristian Van Wambeke <christian.van-wambeke@cea.fr>
Wed, 27 Jun 2018 08:26:39 +0000 (10:26 +0200)
committerChristian Van Wambeke <christian.van-wambeke@cea.fr>
Wed, 27 Jun 2018 08:26:39 +0000 (10:26 +0200)
src/logger.py
src/salomeTools.py
src/xmlManager.py

index 310b157fd5010b191db1a6bfd585315ebc6925c4..f50ae77e85510555dd0b6eee0bffbe8d8023fe92 100755 (executable)
@@ -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")
index 139e3cc2dc9d090aa3d47b247b00f696ce00e75b..ef3857ebc7011f8cf117a20846d3fbff5150c8a7 100755 (executable)
@@ -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      
index ca8ec61e0d35869bd6f33a310ce5d20fe6168a62..d619980da281368a9bf182596bca6b5517c17dee 100644 (file)
@@ -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 '&amp;' and '&lt;' respectively.
+        The right angle bracket(>) may be
+        represented using the string '&gt;', and MUST,
+        for compatibility, be escaped using either '&gt;' 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 &#60; or &lt;
+        > (greater - than) as &#62; or &gt;
+        & (ampersand) as &#38;
+        ' (apostrophe or single quote) as &#39;
+        " (double-quote) as &#34;
+        """
+        replaces = [ ('&', '&amp;'),
+                     ('>', '&gt;'),
+                     ('<', '&lt;'),
+                     ("'", '&#39;'),
+                     ('"', '&#34;'),
+                    ]
+        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