-
Notifications
You must be signed in to change notification settings - Fork 94
fix(#1649): add UploadFile for file-to-file sandbox upload semantics #1651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -377,6 +377,35 @@ func Upload(sandboxName, localPath, remotePath string) error { | |
| return nil | ||
| } | ||
|
|
||
| // UploadFile copies a single local file into a sandbox at a specific remote path. | ||
| // openshell sandbox upload treats the remote path as a directory (similar to | ||
| // docker cp), placing the file inside it with the source basename. This function | ||
| // uploads to the parent directory and renames inside the sandbox if the resulting | ||
| // filename differs from the desired remote name, ensuring file-to-file semantics. | ||
| // This mirrors the DownloadFile approach. | ||
| func UploadFile(sandboxName, localPath, remotePath string) error { | ||
| remoteDir := filepath.Dir(remotePath) | ||
|
|
||
| if err := Upload(sandboxName, localPath, remoteDir); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // openshell places the file as <remoteDir>/<basename(localPath)>. | ||
| // If that differs from the desired remotePath, rename it in-sandbox. | ||
| uploadedPath := filepath.Join(remoteDir, filepath.Base(localPath)) | ||
| if uploadedPath != remotePath { | ||
| mvCmd := fmt.Sprintf("mv %s %s", uploadedPath, remotePath) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [low] injection-defense The mv command in UploadFile uses fmt.Sprintf without shell-quoting paths. Pre-existing pattern but not defensive against paths with spaces or metacharacters. Suggested fix: Use shell-safe quoting for paths in sandbox Exec commands. Consider a helper function for constructing sandbox shell commands. |
||
| _, stderr, exitCode, err := Exec(sandboxName, mvCmd, 10*time.Second) | ||
| if err != nil { | ||
| return fmt.Errorf("renaming uploaded file in sandbox %q: %w", sandboxName, err) | ||
| } | ||
| if exitCode != 0 { | ||
| return fmt.Errorf("renaming uploaded file in sandbox %q: exit %d: %s", sandboxName, exitCode, stderr) | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| // UploadDir uploads a local directory into a sandbox, preserving symlinks. | ||
| // openshell sandbox upload dereferences symlinks; this builds a local tarball | ||
| // with --no-dereference, uploads it, and extracts it in the sandbox. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[low] shell-quoting
UploadFile constructs the in-sandbox mv command via fmt.Sprintf("mv %s %s", ...) without shell-quoting either path. If a path contains spaces or shell metacharacters, the command will fail or behave unexpectedly. Current callers pass safe paths. This matches the pre-existing pattern in UploadDir and is not a regression.
Suggested fix: Use shell-quoted format strings (e.g. single-quote wrapping) consistent with a broader cleanup of the same pattern in UploadDir.