This is an automated email from the ASF dual-hosted git repository. juergbi pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit 4906a347aefe1dc941cfa161d70cac409e4d7741 Merge: 372fee485 d27794a35 Author: Jürg Billeter <[email protected]> AuthorDate: Fri Oct 30 20:44:09 2026 +0100 Merge pull request #2201 from apache/jbilleter/directory-validation Validate `Directory` node names src/buildstream/_cas/cascache.py | 25 +++++++++++++++++++++++++ src/buildstream/storage/_casbaseddirectory.py | 24 ++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --cc src/buildstream/_cas/cascache.py index b0187f296,c649e21bf..4fcdf15c6 --- a/src/buildstream/_cas/cascache.py +++ b/src/buildstream/_cas/cascache.py @@@ -214,25 -218,15 +218,27 @@@ class CASCache os.chmod(fullpath, mode) for dirnode in directory.directories: + _validate_cas_node_name(dirnode.name, names) fullpath = os.path.join(dest, dirnode.name) + # If the destination is a regular file, `os.makedirs()` will catch it. + # However, it will not raise an error if it's a valid directory symlink, + # so check here that we're not unexpectedly following a symlink. + if os.path.islink(fullpath): + raise CASCacheError(f"Destination already exists and is a symlink, not a directory: {fullpath}") self.checkout(fullpath, dirnode.digest, can_link=can_link, _fetch=False) for symlinknode in directory.symlinks: # symlink + _validate_cas_node_name(symlinknode.name, names) fullpath = os.path.join(dest, symlinknode.name) - os.symlink(symlinknode.target, fullpath) + try: + os.symlink(symlinknode.target, fullpath) + except FileExistsError: + try: + os.unlink(fullpath) + except OSError as e: + raise CASCacheError(f"Failed to remove destination file '{fullpath}': {e}") from e + os.symlink(symlinknode.target, fullpath) node_properties = directory.node_properties if node_properties.HasField("mtime"):
