From 23a101b70712e036e4a9e9d8ef54e71b3c3a35e9 Mon Sep 17 00:00:00 2001 From: Shurong Cao <170531907+CAOShurong@users.noreply.github.com> Date: Wed, 12 Aug 2026 14:22:00 +0800 Subject: [PATCH] fix: encode paths when loading XML schemas Signed-off-by: Shurong Cao <170531907+CAOShurong@users.noreply.github.com> --- cyclonedx/validation/xml.py | 3 ++- tests/test_validation_xml.py | 23 ++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/cyclonedx/validation/xml.py b/cyclonedx/validation/xml.py index 14f528088..a65763209 100644 --- a/cyclonedx/validation/xml.py +++ b/cyclonedx/validation/xml.py @@ -20,6 +20,7 @@ from abc import ABC from collections.abc import Iterable +from pathlib import Path from typing import TYPE_CHECKING, Literal, Optional, Union, overload from ..exception import MissingOptionalDependencyException @@ -125,7 +126,7 @@ def _validator(self) -> 'XMLSchema': schema_file = self._schema_file if schema_file is None: raise NotImplementedError('missing schema file') - self.__validator = XMLSchema(file=schema_file) + self.__validator = XMLSchema(file=Path(schema_file).absolute().as_uri()) return self.__validator diff --git a/tests/test_validation_xml.py b/tests/test_validation_xml.py index 2565a85ad..66735f5a4 100644 --- a/tests/test_validation_xml.py +++ b/tests/test_validation_xml.py @@ -18,13 +18,17 @@ from collections.abc import Generator from glob import iglob from itertools import chain -from os.path import join +from os.path import basename, dirname, join +from shutil import copytree +from tempfile import TemporaryDirectory from unittest import TestCase +from unittest.mock import patch from ddt import ddt, idata, unpack from cyclonedx.exception import MissingOptionalDependencyException from cyclonedx.schema import OutputFormat, SchemaVersion +from cyclonedx.schema._res import BOM_XML from cyclonedx.validation.xml import XmlValidator from tests import OWN_DATA_DIRECTORY, SCHEMA_TESTDATA_DIRECTORY, DpTuple @@ -51,6 +55,23 @@ def _dp_sv_own(valid: bool) -> Generator: @ddt class TestXmlValidator(TestCase): + def test_validate_schema_from_path_with_fragment_character(self) -> None: + schema_version = SchemaVersion.V1_6 + schema_file = BOM_XML[schema_version] + self.assertIsNotNone(schema_file) + + with TemporaryDirectory(prefix='cyclonedx#') as temp_directory: + schema_directory = join(temp_directory, 'schemas') + copytree(dirname(schema_file), schema_directory) + copied_schema_file = join(schema_directory, basename(schema_file)) + + with patch.dict('cyclonedx.validation.xml._S_BOM', {schema_version: copied_schema_file}): + validation_error = XmlValidator(schema_version).validate_str( + '' + ) + + self.assertIsNone(validation_error) + @idata(sv for sv in SchemaVersion if sv not in UNSUPPORTED_SCHEMA_VERSIONS) def test_validator_as_expected(self, schema_version: SchemaVersion) -> None: validator = XmlValidator(schema_version)