VYPR
High severityNVD Advisory· Published Mar 20, 2026· Updated Mar 20, 2026

pydicom: Path traversal in FileSet/DICOMDIR ReferencedFileID allows file access outside the File-set root

CVE-2026-32711

Description

pydicom is a pure Python package for working with DICOM files. Versions 2.0.0-rc.1 through 3.0.1 are vulnerable to Path Traversal through a maliciously crafted DICOMDIR ReferencedFileID when it is set to a path outside the File-set root. pydicom resolves the path only to confirm that it exists, but does not verify that the resolved path remains under the File-set root. Subsequent public FileSet operations such as copy(), write(), and remove()+write(use_existing=True) use that unchecked path in file I/O operations. This allows arbitrary file read/copy and, in some flows, move/delete outside the File-set root. This issue has been fixed in version 3.0.2.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

pydicom 2.0.0-rc.1 through 3.0.1 fails to validate that a DICOMDIR's ReferencedFileID stays within the File-set root, enabling arbitrary file read/copy and, in some flows, move/delete.

Root

Cause

The vulnerability lies in how pydicom's FileSet class processes the ReferencedFileID attribute from a DICOMDIR directory record. The _file_id property (later renamed file_id_path) converts the value directly to a pathlib.Path without verifying that the resolved path remains under the File-set root directory [1][2]. The FileSet.load() method only checks that the path exists via (root / file_id).resolve(strict=True), but does not enforce containment [4]. This allows a crafted DICOMDIR to specify absolute paths (e.g., /etc/passwd), traversal sequences (../...), or symlink-based escapes [4].

Exploitation

An attacker can supply a malicious DICOMDIR file (e.g., as part of a DICOM File-set archive) that sets ReferencedFileID to a path outside the intended File-set root. No special authentication is required beyond the ability to have the target application load the DICOMDIR using FileSet [2]. The path traversal is triggered when subsequent public FileSet operations—such as copy(), write(), or remove() combined with write(use_existing=True)—use the unchecked path in file I/O calls like shutil.copyfile(), Path.unlink(), or shutil.move() [4].

Impact

Successful exploitation allows an attacker to read or copy arbitrary files from the server's filesystem to a location accessible via the exported File-set. In some flows, the attacker can also move or delete files outside the File-set root [2][4]. This poses a significant risk in server-side scenarios where a user uploads a DICOM File-set and the server later re-exports or reorganizes it using FileSet operations [4].

Mitigation

The issue has been fixed in pydicom version 3.0.2 [2]. The fix adds a containment check in file_id_path that raises a PermissionError if the resolved path is not relative to the File-set root [1]. Users should upgrade to 3.0.2 or later. No workarounds are documented; however, avoiding the use of FileSet operations on untrusted DICOMDIR files until patched is advisable.

AI Insight generated on May 18, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
pydicomPyPI
>= 3.0.0, < 3.0.23.0.2
pydicomPyPI
< 2.4.52.4.5

Affected products

2
  • pydicom/pydicomllm-create
    Range: >=2.0.0-rc.1, <=3.0.1
  • pydicom/pydicomv5
    Range: >= 2.0.0-rc.1, < 3.0.2

Patches

1
6414f01a053d

Merge from fork - security fix in `FileSet`s

https://github.com/pydicom/pydicomDarcy MasonMar 19, 2026via ghsa
6 files changed · +260 52
  • doc/release_notes/index.rst+1 0 modified
    @@ -2,6 +2,7 @@
     Release notes
     =============
     
    +.. include:: v3.0.2.rst
     .. include:: v3.0.1.rst
     .. include:: v3.0.0.rst
     .. include:: v2.4.0.rst
    
  • doc/release_notes/v3.0.2.rst+8 0 added
    @@ -0,0 +1,8 @@
    +3.0.2
    +=====
    +
    +Fixes
    +-----
    +
    +* Fixed a security issue: a crafted DICOMDIR could set ``ReferencedFileID`` to a path outside the File-set root.
    +  This addresses CVE-2026-32711.
    
  • pyproject.toml+26 1 modified
    @@ -29,7 +29,7 @@ license = {text = "MIT"}
     name = "pydicom"
     readme = "README.md"
     requires-python = ">=3.10"
    -version = "3.0.1"
    +version = "3.0.2"
     
     
     [project.optional-dependencies]
    @@ -55,6 +55,7 @@ dev = [
         "ruff==0.6.3",
         "types-requests",
         "pre-commit",
    +    "pyfakefs>=6.1.6",
     ]
     
     basic = ["numpy", "types-pydicom"]
    @@ -90,6 +91,30 @@ codify = "pydicom.cli.codify:add_subparser"
     show = "pydicom.cli.show:add_subparser"
     
     
    +[dependency-groups]
    +docs = [
    +    "numpy",
    +    "numpydoc",
    +    "matplotlib",
    +    "pillow",
    +    "pydata-sphinx-theme",
    +    "sphinx",
    +    "sphinx-gallery",
    +    "sphinxcontrib-napoleon",
    +    "sphinx-copybutton",
    +    "sphinx_design",
    +]
    +
    +dev = [
    +    "pydicom-data",
    +    "pyfakefs",
    +    "pytest",
    +    "pytest-cov",
    +    "types-requests",
    +    "pre-commit",
    +]
    +
    +
     [tool.black]
     exclude = ".venv|build|/_.*_dict.py$"
     force-exclude = ".venv|/_.*_dict.py$"  # to not do files pre-commit asks for
    
  • src/pydicom/fileset.py+105 36 modified
    @@ -346,24 +346,47 @@ def _encode_record(self, force_implicit: bool = False) -> int:
     
             return len(fp.getvalue())
     
    -    @property
    -    def _file_id(self) -> Path | None:
    +    def file_id_path(self, root_path: Path) -> Path | None:
             """Return the *Referenced File ID* as a :class:`~pathlib.Path`.
     
    +        Params
    +        ------
    +        root_path : Path
    +            The root path of the parent file set.
    +
             Returns
             -------
             pathlib.Path or None
                 The *Referenced File ID* from the directory record as a
                 :class:`pathlib.Path` or ``None`` if the element value is null.
    +
    +        Raises
    +        ------
    +        PermissionError
    +            If the file ID points to a path outside the fileset root path.
    +
    +        AttributeError
    +            If the Referenced File ID is missing in the directory record.
    +
    +        :meta private:
             """
             if "ReferencedFileID" in self._record:
                 elem = self._record["ReferencedFileID"]
    +            if elem.VM < 1:
    +                return None
                 if elem.VM == 1:
    -                return Path(cast(str, self._record.ReferencedFileID))
    -            if elem.VM > 1:
    -                return Path(*cast(list[str], self._record.ReferencedFileID))
    -
    -            return None
    +                path = Path(cast(str, self._record.ReferencedFileID))
    +            else:
    +                path = Path(*cast(list[str], self._record.ReferencedFileID))
    +
    +            if path is not None:
    +                if path.anchor or not (
    +                    (root_path / path).resolve().is_relative_to(root_path)
    +                ):
    +                    raise PermissionError(
    +                        f"ReferencedFileID ('{path}') must be inside the DICOMDIR root path"
    +                    )
    +            return path
     
             raise AttributeError("No 'Referenced File ID' in the directory record")
     
    @@ -373,7 +396,7 @@ def file_set(self) -> "FileSet":
             return self.root.file_set
     
         def __getitem__(self, key: Union[str, "RecordNode"]) -> "RecordNode":
    -        """Return the current node's child using it's
    +        """Return the current node's child using its
             :attr:`~pydicom.fileset.RecordNode.key`
             """
             if isinstance(key, RecordNode):
    @@ -525,7 +548,7 @@ def leaf_summary(node: "RecordNode", indent_char: str) -> list[str]:
                 indent = indent_char * node.depth
                 if node.children:
                     s.append(f"{indent}{node}")
    -                # Summarise any leaves at the next level
    +                # Summarize any leaves at the next level
                     for child in node.children:
                         if child.has_instance:
                             s.extend(leaf_summary(child, indent_char))
    @@ -926,9 +949,8 @@ def path(self) -> str:
                 return os.fspath(cast(Path, self._stage_path))
     
             # If not staged for addition then File Set must exist on file system
    -        return os.fspath(
    -            cast(Path, self.file_set.path) / cast(Path, self.node._file_id)
    -        )
    +        root_path = self.file_set.root_path
    +        return os.fspath(root_path / cast(Path, self.node.file_id_path(root_path)))
     
         @property
         def SOPClassUID(self) -> UID:
    @@ -962,7 +984,7 @@ def __init__(self, ds: DSPathType | None = None) -> None:
                 to the DICOMDIR file.
             """
             # The nominal path to the root of the File-set
    -        self._path: Path | None = None
    +        self._root_path: Path | None = None
             # The root node of the record tree used to fill out the DICOMDIR's
             #   *Directory Record Sequence*.
             # The tree for instances currently in the File-set
    @@ -1203,7 +1225,7 @@ def clear(self) -> None:
             """Clear the File-set."""
             self._tree.children = []
             self._instances = []
    -        self._path = None
    +        self._root_path = None
             self._ds = Dataset()
             self._id = None
             self._uid = generate_uid()
    @@ -1635,7 +1657,7 @@ def load(
                 )
     
             try:
    -            path = Path(cast(str, ds.filename)).resolve(strict=True)
    +            path = Path(ds.filename).resolve(strict=True)
             except FileNotFoundError:
                 raise FileNotFoundError(
                     "Unable to load the File-set as the 'filename' attribute "
    @@ -1661,7 +1683,7 @@ def load(
             self._charset = cast(
                 str | None, ds.get("SpecificCharacterSetOfFileSetDescriptorFile", None)
             )
    -        self._path = path.parent
    +        self._root_path = path.parent
             self._ds = ds
     
             # Create the record tree
    @@ -1670,20 +1692,17 @@ def load(
             bad_instances = []
             for instance in self:
                 # Check that the referenced file exists
    -            file_id = instance.node._file_id
    -            if file_id is None:
    -                bad_instances.append(instance)
    -                continue
    -
    +            file_id = self._file_id_path(instance.node)
    +            assert file_id is not None
                 try:
                     # self.path is already set at this point
    -                (cast(Path, self.path) / file_id).resolve(strict=True)
    +                (self.root_path / file_id).resolve(strict=True)
                 except FileNotFoundError:
                     bad_instances.append(instance)
                     warn_and_log(
                         "The referenced SOP Instance for the directory record at "
                         f"offset {instance.node._offset} does not exist: "
    -                    f"{cast(Path, self.path) / file_id}"
    +                    f"{self.root_path / file_id}"
                     )
                     continue
     
    @@ -1695,6 +1714,31 @@ def load(
             for instance in bad_instances:
                 self._instances.remove(instance)
     
    +    def _file_id_path(self, node: RecordNode) -> Path | None:
    +        """Return the *Referenced File ID* from the given node
    +        as a :class:`~pathlib.Path`.
    +
    +        Parameters
    +        ----------
    +        node: RecordNode
    +            The node where the *Referenced File ID* resides.
    +
    +        Returns
    +        -------
    +        pathlib.Path or None
    +            The *Referenced File ID* from the directory record as a
    +            :class:`pathlib.Path` or ``None`` if the element value is null.
    +
    +        Raises
    +        ------
    +        PermissionError
    +            If the file ID points to a path outside the fileset root path.
    +
    +        AttributeError
    +            If the Referenced File ID is missing in the directory record.
    +        """
    +        return node.file_id_path(self.root_path)
    +
         def _parse_records(
             self, ds: Dataset, include_orphans: bool, raise_orphans: bool = False
         ) -> None:
    @@ -1748,7 +1792,10 @@ def recurse_node(node: RecordNode) -> None:
                     del node.parent[node]
     
                 # The leaf node references the FileInstance
    -            if "ReferencedFileID" in node._record:
    +            if (
    +                "ReferencedFileID" in node._record
    +                and self._file_id_path(node) is not None
    +            ):
                     node.instance = FileInstance(node)
                     self._instances.append(node.instance)
     
    @@ -1781,12 +1828,11 @@ def recurse_node(node: RecordNode) -> None:
             for node in missing:
                 # Get the path to the orphaned instance
                 original_value = node._record.ReferencedFileID
    -            file_id = node._file_id
    -            if file_id is None:
    +            if (file_id := self._file_id_path(node)) is None:
                     continue
     
                 # self.path is set for an existing File Set
    -            path = cast(Path, self.path) / file_id
    +            path = self.root_path / file_id
                 if node.record_type == "PRIVATE":
                     instance = self.add_custom(path, node)
                 else:
    @@ -1795,15 +1841,30 @@ def recurse_node(node: RecordNode) -> None:
                 # Because the record is new the Referenced File ID isn't set
                 instance.node._record.ReferencedFileID = original_value
     
    +    @property
    +    def root_path(self) -> Path:
    +        """Return the absolute path to the File-set root directory as
    +        :class:`pathlib.Path`.
    +
    +        Raises
    +        ------
    +        AttributeError
    +            If the root path is not set.
    +        """
    +        if self._root_path is None:
    +            raise AttributeError("No root path set in the File-set")
    +
    +        return self._root_path
    +
         @property
         def path(self) -> str | None:
             """Return the absolute path to the File-set root directory as
             :class:`str` (if set) or ``None`` otherwise.
             """
    -        if self._path is not None:
    -            return os.fspath(self._path)
    +        if self._root_path is not None:
    +            return os.fspath(self._root_path)
     
    -        return self._path
    +        return None
     
         def _recordify(self, ds: Dataset) -> Iterator[Dataset]:
             """Yield directory records for a SOP Instance.
    @@ -2062,14 +2123,15 @@ def write(
                 )
     
             if path:
    -            self._path = Path(path)
    +            self._root_path = Path(path)
     
             # Don't write unless changed or new
             if not self.is_staged:
                 return
     
             # Path to the DICOMDIR file
    -        p = cast(Path, self._path) / "DICOMDIR"
    +        root = self.root_path
    +        p = root / "DICOMDIR"
     
             # Re-use the existing directory structure if only moves or removals
             #   are required and `use_existing` is True
    @@ -2117,13 +2179,20 @@ def write(
             #   and copy any to the stage
             fout = {Path(ii.FileID) for ii in self}
             fin = {
    -            ii.node._file_id for ii in self if ii.SOPInstanceUID not in self._stage["+"]
    +            self._file_id_path(ii.node)
    +            for ii in self
    +            if ii.SOPInstanceUID not in self._stage["+"]
             }
             collisions = fout & fin
    -        for instance in [ii for ii in self if ii.node._file_id in collisions]:
    +        for instance in [
    +            ii for ii in self if self._file_id_path(ii.node) in collisions
    +        ]:
                 self._stage["+"][instance.SOPInstanceUID] = instance
                 instance._apply_stage("+")
    -            shutil.copyfile(self._path / instance.node._file_id, instance.path)
    +            shutil.copyfile(
    +                root / cast(Path, self._file_id_path(instance.node)),
    +                instance.path,
    +            )
     
             for instance in self:
                 dst = self._path / instance.FileID
    @@ -2133,7 +2202,7 @@ def write(
                     src = instance.path
                     fn = shutil.copyfile
                 else:
    -                src = self._path / instance.node._file_id
    +                src = root / cast(Path, self._file_id_path(instance.node))
                     fn = shutil.move
     
                 fn(os.fspath(src), os.fspath(dst))
    
  • tests/conftest.py+8 0 modified
    @@ -21,6 +21,14 @@ def allow_reading_invalid_values():
         config.settings.reading_validation_mode = value
     
     
    +@pytest.fixture
    +def ignore_reading_invalid_values():
    +    value = config.settings.reading_validation_mode
    +    config.settings.reading_validation_mode = config.IGNORE
    +    yield
    +    config.settings.reading_validation_mode = value
    +
    +
     @pytest.fixture
     def enforce_writing_invalid_values():
         value = config.settings.writing_validation_mode
    
  • tests/test_fileset.py+112 15 modified
    @@ -9,7 +9,7 @@
     from pydicom import dcmread
     from pydicom.data import get_testdata_file
     from pydicom.dataset import Dataset, FileMetaDataset
    -from pydicom.filebase import DicomBytesIO
    +from pydicom.filebase import DicomBytesIO, DicomFileLike
     from pydicom.fileset import (
         FileSet,
         FileInstance,
    @@ -106,6 +106,56 @@ def tdir():
         return TemporaryDirectory()
     
     
    +FILESET_ROOT = "/path/to/fileset/"
    +ABS_FILE_PATH = "/secret.txt"
    +SYMLINK_TO_ABS_FILE = "Pat1/St1/Im2"
    +SYMLINK_TO_ABS_DIR = "Pat1/St2"
    +DOT_DOT_FILE = "../goback.txt"
    +ABS_FILE_CONTENTS = "Top Secret file contents"
    +COPY_PATH = "/path/to/copied/"
    +
    +
    +@pytest.fixture(
    +    params=[
    +        ABS_FILE_PATH,
    +        DOT_DOT_FILE,
    +        SYMLINK_TO_ABS_FILE,
    +        SYMLINK_TO_ABS_DIR + ABS_FILE_PATH,
    +    ]
    +)
    +def fileset_fs(request, fs, ignore_reading_invalid_values):
    +    """Create an in-memory file system with pyfakefs and test DICOMDIRs"""
    +    # Simplified version of submitted report from JeongAhn Jang, in pyfakefs
    +    orig_dicomdir_root = Path(TEST_FILE).parent
    +    dicomdir_root = Path(FILESET_ROOT)
    +    fs.add_real_file(
    +        orig_dicomdir_root / "77654033/CR1/6154",
    +        target_path=dicomdir_root / "Pat1/St1/Im1",
    +    )
    +    fs.create_file(ABS_FILE_PATH, contents=ABS_FILE_CONTENTS)
    +    fs.create_dir(COPY_PATH)
    +    fs.create_symlink(dicomdir_root / SYMLINK_TO_ABS_FILE, ABS_FILE_PATH)
    +    fs.create_symlink(dicomdir_root / SYMLINK_TO_ABS_DIR, "/")
    +    # MAKE DICOMDIR for this simplified file-set
    +    fset = FileSet()
    +    fset.add(dicomdir_root / "Pat1/St1/Im1")
    +    fset.write(dicomdir_root)
    +
    +    # Create bad DICOMDIR2 file from the simplified one
    +    # Modify first referenced file
    +    fset = FileSet(dicomdir_root / "DICOMDIR")
    +    record = next(
    +        rec for rec in fset._ds.DirectoryRecordSequence if "ReferencedFileID" in rec
    +    )
    +    record.ReferencedFileID = request.param
    +
    +    # Write modified DICOMDIR file
    +    with open(dicomdir_root / "DICOMDIR2", "wb") as fp:
    +        fset._write_dicomdir(DicomFileLike(fp))
    +
    +    yield fs
    +
    +
     @pytest.fixture
     def custom_leaf():
         """Return the leaf node from a custom 4-level record hierarchy"""
    @@ -139,7 +189,7 @@ def custom_leaf():
     
     
     @pytest.fixture
    -def private(dicomdir):
    +def private(dicomdir, request, ignore_reading_invalid_values):
         """Return a DICOMDIR dataset with PRIVATE records."""
     
         def write_record(ds):
    @@ -167,13 +217,17 @@ def private_record():
         middle = private_record()
         bottom = private_record()
         bottom.ReferencedSOPClassUIDInFile = "1.2.3.4"
    -    bottom.ReferencedFileID = [
    -        "TINY_ALPHA",
    -        "PT000000",
    -        "ST000000",
    -        "SE000000",
    -        "IM000000",
    -    ]
    +    if hasattr(request, "param"):
    +        file_ids = request.param
    +    else:
    +        file_ids = [
    +            "TINY_ALPHA",
    +            "PT000000",
    +            "ST000000",
    +            "SE000000",
    +            "IM000000",
    +        ]
    +    bottom.ReferencedFileID = file_ids
         bottom.ReferencedSOPInstanceUIDInFile = (
             "1.2.276.0.7230010.3.1.4.0.31906.1359940846.78187"
         )
    @@ -683,6 +737,15 @@ def test_key_raises(self, dummy):
             with pytest.raises(AttributeError, match=msg):
                 instance.node.key
     
    +    @pytest.mark.parametrize("private", [["/", "etc", "passwd"]], indirect=True)
    +    def test_id_outside_root(self, private):
    +        """File ID points to a path outside the root directory."""
    +        with pytest.raises(
    +            PermissionError,
    +            match=r"ReferencedFileID .* must be inside the DICOMDIR root path",
    +        ):
    +            FileSet(private)
    +
         def test_bad_record(self, private):
             """Test a bad directory record raises an exception when loading."""
             del private.DirectoryRecordSequence[0].PatientID
    @@ -745,7 +808,33 @@ def test_file_id_singleton(self, ct, tdir):
             item.ReferencedFileID = "01"
             ds.save_as(p / "DICOMDIR", overwrite=True)
             fs = FileSet(ds)
    -        assert fs._instances[0].node._file_id == Path("01")
    +        assert fs._instances[0].node.file_id_path(fs.root_path) == Path("01")
    +
    +    def test_absolute_file_id(self, ct, tdir, ignore_reading_invalid_values):
    +        """Test a singleton File ID."""
    +        fs = FileSet()
    +        p = Path(tdir.name)
    +        ct.save_as(p / "01")
    +        fs.add(p / "01")
    +        fs.write(p)
    +        ds = dcmread(p / "DICOMDIR")
    +        item = ds.DirectoryRecordSequence[-1]
    +        item.ReferencedFileID = "/01"
    +        ds.save_as(p / "DICOMDIR", overwrite=True)
    +        with pytest.raises(
    +            PermissionError,
    +            match=r"ReferencedFileID .* must be inside the DICOMDIR root path",
    +        ):
    +            FileSet(ds)
    +
    +    def test_root_path_missing(self, ct):
    +        """Test RecordNode._file_id if no Referenced File ID."""
    +        fs = FileSet()
    +        instance = fs.add(ct)
    +        # del instance.node._record.ReferencedFileID
    +        msg = r"No root path set in the File-set"
    +        with pytest.raises(AttributeError, match=msg):
    +            fs.root_path
     
         def test_file_id_missing(self, ct):
             """Test RecordNode._file_id if no Referenced File ID."""
    @@ -754,7 +843,7 @@ def test_file_id_missing(self, ct):
             del instance.node._record.ReferencedFileID
             msg = r"No 'Referenced File ID' in the directory record"
             with pytest.raises(AttributeError, match=msg):
    -            instance.node._file_id
    +            instance.node.file_id_path(Path("/dicom_data"))
     
     
     class TestFileInstance:
    @@ -1673,7 +1762,7 @@ def test_clear(self, dicomdir, tdir):
             assert "ISO 1" == fs.descriptor_character_set
             assert [] != fs._instances
             assert fs._id is not None
    -        assert fs._path is not None
    +        assert fs.root_path is not None
             uid = fs._uid
             assert fs._uid is not None
             assert fs._ds is not None
    @@ -1684,7 +1773,7 @@ def test_clear(self, dicomdir, tdir):
             fs.clear()
             assert [] == fs._instances
             assert fs._id is None
    -        assert fs._path is None
    +        assert fs._root_path is None
             assert uid != fs._uid
             assert fs._uid.is_valid
             assert fs._ds == Dataset()
    @@ -2328,14 +2417,14 @@ def test_write_use_existing(self, dicomdir_copy):
             tdir, ds = dicomdir_copy
             assert 52 == len(ds.DirectoryRecordSequence)
             fs = FileSet(ds)
    -        orig_paths = [p for p in fs._path.glob("**/*") if p.is_file()]
    +        orig_paths = [p for p in fs.root_path.glob("**/*") if p.is_file()]
             instance = fs._instances[0]
             assert Path(instance.path) in orig_paths
             fs.remove(instance)
             orig_file_ids = [ii.ReferencedFileID for ii in fs]
             fs.write(use_existing=True)
             assert 50 == len(fs._ds.DirectoryRecordSequence)
    -        paths = [p for p in fs._path.glob("**/*") if p.is_file()]
    +        paths = [p for p in fs.root_path.glob("**/*") if p.is_file()]
             assert orig_file_ids == [ii.ReferencedFileID for ii in fs]
             assert Path(instance.path) not in paths
             assert sorted(orig_paths)[1:] == sorted(paths)
    @@ -2487,6 +2576,14 @@ def setup_method(self):
         def teardown_method(self):
             FileSet.__len__ = self.orig
     
    +    def test_constrained_to_fileset_root(self, fileset_fs):
    +        """Ensure files cannot be copied outside the FileSet root"""
    +        with pytest.raises(
    +            PermissionError,
    +            match=r"ReferencedFileID .* must be inside the DICOMDIR root path",
    +        ):
    +            FileSet(Path(FILESET_ROOT) / "DICOMDIR2")
    +
         def test_copy(self, dicomdir, tdir):
             """Test FileSet.copy()"""
             orig_root = Path(dicomdir.filename).parent
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.