Skip to content

Use shutil instead of os.system('cp -r') in LocalConnector upload/download#19

Open
rayair250-droid wants to merge 1 commit into
chenggroup:mainfrom
rayair250-droid:fix/local-connector-shutil
Open

Use shutil instead of os.system('cp -r') in LocalConnector upload/download#19
rayair250-droid wants to merge 1 commit into
chenggroup:mainfrom
rayair250-droid:fix/local-connector-shutil

Conversation

@rayair250-droid

Copy link
Copy Markdown

The LocalConnector.upload and download methods copy files by shelling out to cp -r via os.system with f-string-interpolated paths:

os.system(f"cp -r {from_path} {to_dir}")

This breaks whenever from_path/to_dir contain spaces or shell metacharacters (a real case for user-provided working directories), is a shell-injection surface, and is Unix-only.

This replaces both with shutil, handling file and directory sources (as cp -r does):

to_path = os.path.join(to_dir, safe_basename(from_path))
if os.path.isdir(from_path):
    shutil.copytree(from_path, to_path, dirs_exist_ok=True)
else:
    shutil.copy2(from_path, to_path)
return to_path

Shell-free, robust to special characters, and portable. Return value is unchanged. Verified the copy logic on both a file (with a space in its name) and a directory.

…nload

The local upload/download methods shelled out to 'cp -r' via os.system with f-string-interpolated paths, which breaks on paths containing spaces or shell metacharacters (and is Unix-only). Replace with shutil.copytree/copy2, handling both file and directory sources, so copies are shell-free, robust to special characters, and portable.
@link89

link89 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Thank you for catching this. The choice of cp -r over Python's shutil was because cp -r has specific, built-in logic handling target directory existence. I couldn't guarantee shutil would mirror that exact behavior, so I opted for the simpler approach.

Since this feature is now deprecated, I prefer a straightforward fix: wrap both the source and target paths using shlex.quote() when generating the cp command.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants