Addon Manager: Don't crash on bad XML

Wrap all metadata reads in try/except blocks and gracefully bail out if the data is bad.
This commit is contained in:
Chris Hennes
2024-09-18 21:17:49 -05:00
parent 4e0a574141
commit 72c654df55
3 changed files with 48 additions and 11 deletions

View File

@@ -30,6 +30,7 @@ from urllib.parse import urlparse
from typing import Dict, Set, List, Optional
from threading import Lock
from enum import IntEnum, auto
import xml.etree.ElementTree
import addonmanager_freecad_interface as fci
from addonmanager_macro import Macro
@@ -372,7 +373,14 @@ class Addon:
"""Read a given metadata file and set it as this object's metadata"""
if os.path.exists(file):
metadata = MetadataReader.from_file(file)
try:
metadata = MetadataReader.from_file(file)
except xml.etree.ElementTree.ParseError:
fci.Console.PrintWarning(
"An invalid or corrupted package.xml file was found in the cache for"
)
fci.Console.PrintWarning(f" {self.name}... ignoring the bad data.\n")
return
self.set_metadata(metadata)
self._clean_url()
else:
@@ -384,7 +392,14 @@ class Addon:
mod_dir = os.path.join(self.mod_directory, self.name)
installed_metadata_path = os.path.join(mod_dir, "package.xml")
if os.path.isfile(installed_metadata_path):
self.installed_metadata = MetadataReader.from_file(installed_metadata_path)
try:
self.installed_metadata = MetadataReader.from_file(installed_metadata_path)
except xml.etree.ElementTree.ParseError:
fci.Console.PrintWarning(
"An invalid or corrupted package.xml file was found in installation of"
)
fci.Console.PrintWarning(f" {self.name}... ignoring the bad data.\n")
return
def set_metadata(self, metadata: Metadata) -> None:
"""Set the given metadata object as this object's metadata, updating the

View File

@@ -30,6 +30,7 @@ import json
import os
from typing import Dict
from enum import Enum, auto
import xml.etree.ElementTree
from PySide import QtCore
@@ -188,7 +189,12 @@ class UpdateMetadataCacheWorker(QtCore.QThread):
with open(new_xml_file, "w", encoding="utf-8") as f:
string_data = self._ensure_string(data, repo.name, "package.xml")
f.write(string_data)
metadata = MetadataReader.from_file(new_xml_file)
try:
metadata = MetadataReader.from_file(new_xml_file)
except xml.etree.ElementTree.ParseError:
fci.Console.PrintWarning("An invalid or corrupted package.xml file was downloaded for")
fci.Console.PrintWarning(f" {self.name}... ignoring the bad data.\n")
return
repo.set_metadata(metadata)
FreeCAD.Console.PrintLog(f"Downloaded package.xml for {repo.name}\n")
self.status_message.emit(

View File

@@ -33,6 +33,7 @@ import stat
import threading
import time
from typing import List
import xml.etree.ElementTree
from PySide import QtCore
@@ -44,6 +45,7 @@ from AddonStats import AddonStats
import NetworkManager
from addonmanager_git import initialize_git, GitFailed
from addonmanager_metadata import MetadataReader, get_branch_from_metadata
import addonmanager_freecad_interface as fci
translate = FreeCAD.Qt.translate
@@ -193,10 +195,18 @@ class CreateAddonListWorker(QtCore.QThread):
repo = Addon(name, addon["url"], state, addon["branch"])
md_file = os.path.join(addondir, "package.xml")
if os.path.isfile(md_file):
repo.installed_metadata = MetadataReader.from_file(md_file)
repo.installed_version = repo.installed_metadata.version
repo.updated_timestamp = os.path.getmtime(md_file)
repo.verify_url_and_branch(addon["url"], addon["branch"])
try:
repo.installed_metadata = MetadataReader.from_file(md_file)
repo.installed_version = repo.installed_metadata.version
repo.updated_timestamp = os.path.getmtime(md_file)
repo.verify_url_and_branch(addon["url"], addon["branch"])
except xml.etree.ElementTree.ParseError:
fci.Console.PrintWarning(
"An invalid or corrupted package.xml file was installed for"
)
fci.Console.PrintWarning(
f" custom addon {self.name}... ignoring the bad data.\n"
)
self.addon_repo.emit(repo)
@@ -236,10 +246,16 @@ class CreateAddonListWorker(QtCore.QThread):
repo = Addon(name, url, state, branch)
md_file = os.path.join(addondir, "package.xml")
if os.path.isfile(md_file):
repo.installed_metadata = MetadataReader.from_file(md_file)
repo.installed_version = repo.installed_metadata.version
repo.updated_timestamp = os.path.getmtime(md_file)
repo.verify_url_and_branch(url, branch)
try:
repo.installed_metadata = MetadataReader.from_file(md_file)
repo.installed_version = repo.installed_metadata.version
repo.updated_timestamp = os.path.getmtime(md_file)
repo.verify_url_and_branch(url, branch)
except xml.etree.ElementTree.ParseError:
fci.Console.PrintWarning(
"An invalid or corrupted package.xml file was installed for"
)
fci.Console.PrintWarning(f" addon {self.name}... ignoring the bad data.\n")
if name in self.py2only:
repo.python2 = True