Repository: ericsson/codechecker
Issue: Report converter crashes when converting corrupted cppcheck results

**Describe the bug**
After analyzing LLVM on the `llvmorg-9.0.0` tag with CppCheck on commit e9b7e7811be942b5ffe20d424baf0e2db30355bd with the following command:
```bash
$ cppcheck --enable=all --project=compile_commands.json --plist-output=results/cppcheck_pre -j12
```
converting fails:
```bash
$ report-converter --type cppcheck results/cppcheck_pre/AssemblerTest.plist -o results/cppcheck_results -v
Traceback (most recent call last):
  File "codechecker/tools/report-converter/venv/bin/report-converter", line 11, in <module>
    load_entry_point('report-converter', 'console_scripts', 'report-converter')()
  File "codechecker/tools/report-converter/codechecker_report_converter/cli.py", line 123, in main
    args.clean)       
  File "codechecker/tools/report-converter/codechecker_report_converter/cli.py", line 64, in output_to_plist
    parser.transform(analyzer_result, output_dir)
  File "codechecker/tools/report-converter/codechecker_report_converter/analyzer_result.py", line 35, in transform
    plist_objs = self.parse(analyzer_result)
  File "codechecker/tools/report-converter/codechecker_report_converter/cppcheck/analyzer_result.py", line 51, in parse
    file_to_plist_data[file_name] = plistlib.readPlist(f)
  File "/usr/lib/python2.7/plistlib.py", line 78, in readPlist
    rootObject = p.parse(pathOrFile)                          
  File "/usr/lib/python2.7/plistlib.py", line 406, in parse
    parser.ParseFile(fileobj)       
xml.parsers.expat.ExpatError: junk after document element: line 364, column 8
 ```

Its worth noting that the plist file is incorrect -- I suspect running multiple jobs messes with CppCheck.

**CodeChecker version**
The report converter was built on commit 7cbfce477ccbfc0c2f0df59aacc031ba8a451d6d.

**Expected behavior**
Emit a proper error message about the incorrect file.

**Desktop (please complete the following information)**
 - OS: Ubuntu 18.04

**Additional context**
I generated the plist file on a server, but I could reproduce the crash by simply copying said plist file and trying to convert locally, so I attached it:
[AssemblerTest.zip](https://github.com/Ericsson/codechecker/files/4204754/AssemblerTest.zip)





Changed files:
tools/report-converter/codechecker_report_converter/cppcheck/analyzer_result.py

diff --git a/tools/report-converter/codechecker_report_converter/cppcheck/analyzer_result.py b/tools/report-converter/codechecker_report_converter/cppcheck/analyzer_result.py
index d6cd48ad..1fa683e0 100644
--- a/tools/report-converter/codechecker_report_converter/cppcheck/analyzer_result.py
+++ b/tools/report-converter/codechecker_report_converter/cppcheck/analyzer_result.py
@@ -12,6 +12,8 @@ import logging
 import os
 import plistlib
 
+from xml.parsers.expat import ExpatError
+
 from codechecker_report_converter.analyzer_result import AnalyzerResult
 from codechecker_report_converter.report import generate_report_hash
 
@@ -47,8 +49,12 @@ class CppcheckAnalyzerResult(AnalyzerResult):
             plist_file = os.path.basename(f)
             file_name = '{0}_{1}.plist'.format(os.path.splitext(plist_file)[0],
                                                self.TOOL_NAME)
+
             with open(f, 'rb') as plist_file:
-                file_to_plist_data[file_name] = plistlib.load(plist_file)
+                try:
+                    file_to_plist_data[file_name] = plistlib.load(plist_file)
+                except ExpatError:
+                    LOG.error("Failed to parse '%s'! Skipping...", file_name)
 
         return file_to_plist_data
 
@@ -58,9 +64,14 @@ class CppcheckAnalyzerResult(AnalyzerResult):
         By default it will add report hashes and metada information for the
         diagnostics.
         """
-        for _, plist_data in file_to_plist_data.items():
-            self._add_report_hash(plist_data)
-            self._add_metadata(plist_data)
+        for file_name, plist_data in file_to_plist_data.items():
+            try:
+                self._add_report_hash(plist_data)
+                self._add_metadata(plist_data)
+            except IndexError:
+                LOG.warning("Failed to update '%s' while generating a report "
+                            "hash! Skipping...", file_name)
+                file_to_plist_data[file_name] = None
 
     def _add_report_hash(self, plist_data):
         """ Generate report hash for the given plist data