Repository: google/turbinia
Pull request #454 (2019-10-25 17:36:44)

Method to check for xml attribs for report generation in bulk extractor worker
Added a method in the bulk extractor worker that will check for the existence of a given xml value before trying to grab it's text. This prevents the whole report from failing in the event there is a missing field in the report.


Patch:
diff --git a/turbinia/workers/bulk_extractor.py b/turbinia/workers/bulk_extractor.py
index 4817e46..6704559 100644
--- a/turbinia/workers/bulk_extractor.py
+++ b/turbinia/workers/bulk_extractor.py
@@ -72,6 +72,23 @@ class BulkExtractorTask(TurbiniaTask):
       return result
     return result
 
+  def check_xml_attrib(self, xml_key):
+    """Checks if a key exists within the xml report.
+
+    Args:
+      xml_key(str): the xml key to check for.
+
+    Returns:
+      xml_hit(str): the xml value else return N/A.
+    """
+    xml_hit = 'N/A'
+    xml_search = self.xml.find(xml_key)
+
+    # If exists, return the text value.
+    if xml_search is not None:
+      xml_hit = xml_search.text
+    return xml_hit
+
   def generate_summary_report(self, output_file_path):
     """Generate a summary report from the resulting bulk extractor run.
 
@@ -93,7 +110,7 @@ class BulkExtractorTask(TurbiniaTask):
       return (report, report)
 
     # Parse existing XML file.
-    xml = xml_tree.parse(report_path)
+    self.xml = xml_tree.parse(report_path)
 
     # Place in try/except statement to continue execution when
     # an attribute is not found and NoneType is returned.
@@ -104,23 +121,25 @@ class BulkExtractorTask(TurbiniaTask):
       findings.append(
           fmt.bullet(
               'Program: {0} - {1}'.format(
-                  xml.find('creator/program').text,
-                  xml.find('creator/version').text)))
+                  self.check_xml_attrib('creator/program'),
+                  self.check_xml_attrib('creator/version'))))
       findings.append(
           fmt.bullet(
               'Command Line: {0}'.format(
-                  xml.find('creator/execution_environment/command_line').text)))
+                  self.check_xml_attrib(
+                      'creator/execution_environment/command_line'))))
       findings.append(
           fmt.bullet(
               'Start Time: {0}'.format(
-                  xml.find('creator/execution_environment/start_time').text)))
+                  self.check_xml_attrib(
+                      'creator/execution_environment/start_time'))))
       findings.append(
           fmt.bullet(
               'Elapsed Time: {0}'.format(
-                  xml.find('report/elapsed_seconds').text)))
+                  self.check_xml_attrib('report/elapsed_seconds'))))
 
       # Retrieve results from each of the scanner runs
-      feature_files = xml.find('feature_files')
+      feature_files = self.xml.find('feature_files')
       if feature_files is not None:
         feature_iter = feature_files.iter()
         findings.append(fmt.heading5('Scanner Results'))


Test patch:
diff --git a/turbinia/workers/bulk_extractor_test.py b/turbinia/workers/bulk_extractor_test.py
index df81094..978e002 100644
--- a/turbinia/workers/bulk_extractor_test.py
+++ b/turbinia/workers/bulk_extractor_test.py
@@ -20,8 +20,8 @@ from io import StringIO
 
 import os
 import unittest
-import mock
 import textwrap
+import mock
 
 from turbinia.evidence import BulkExtractorOutput
 from turbinia.workers import bulk_extractor
@@ -66,7 +66,7 @@ class BulkExtractorTaskTest(TestTurbiniaTaskBase):
         * Program: BULK_EXTRACTOR - 1.6.0-dev
         * Command Line: bulk_extractor /tmp/test-small.img -o /output/test-small.img
         * Start Time: 2019-09-27T16:34:48Z
-        * Elapsed Time: 2.389155
+        * Elapsed Time: N/A
         ##### There are no findings to report.""")
 
     summary_sample = "0 artifacts have been extracted."
@@ -82,9 +82,6 @@ class BulkExtractorTaskTest(TestTurbiniaTaskBase):
             <start_time>2019-09-27T16:34:48Z</start_time>
           </execution_environment>
         </creator>
-        <report>
-          <elapsed_seconds>2.389155</elapsed_seconds>
-        </report>
         </dfxml>""")
 
     str_io = StringIO(xml_sample)