Add file upload functionality to the agent. Implement API endpoint for uploading files, including validation and error handling. Update web interface to support file selection and display upload status. Enhance input handling with configurable key delay for text input.
This commit is contained in:
@@ -129,3 +129,40 @@ func isWithin(root, candidate string) bool {
|
||||
}
|
||||
return rel != ".." && !strings.HasPrefix(rel, ".."+string(os.PathSeparator)) && !filepath.IsAbs(rel)
|
||||
}
|
||||
|
||||
var ErrBadUploadName = errors.New("invalid upload file name")
|
||||
|
||||
func SafeUploadName(name string) (string, error) {
|
||||
name = strings.TrimSpace(name)
|
||||
if name == "" {
|
||||
return "", ErrBadUploadName
|
||||
}
|
||||
name = filepath.Base(name)
|
||||
if name == "" || name == "." || name == ".." {
|
||||
return "", ErrBadUploadName
|
||||
}
|
||||
return name, nil
|
||||
}
|
||||
|
||||
func UploadTarget(root, dir, filename string) (string, error) {
|
||||
safeName, err := SafeUploadName(filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
cleanDir, err := AllowedPath(root, dir, true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
info, err := os.Stat(cleanDir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return "", errors.New("path is not a directory")
|
||||
}
|
||||
target := filepath.Join(cleanDir, safeName)
|
||||
if root != "" && !isWithin(root, target) {
|
||||
return "", ErrOutsideRoot
|
||||
}
|
||||
return target, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package files
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestSafeUploadName(t *testing.T) {
|
||||
t.Parallel()
|
||||
cases := map[string]bool{
|
||||
"notes.txt": true,
|
||||
"../evil.exe": true, // basename keeps evil.exe
|
||||
"..": false,
|
||||
".": false,
|
||||
"": false,
|
||||
`C:\temp\foo.txt`: true,
|
||||
}
|
||||
for name, wantOK := range cases {
|
||||
got, err := SafeUploadName(name)
|
||||
if wantOK {
|
||||
if err != nil {
|
||||
t.Fatalf("SafeUploadName(%q) err = %v", name, err)
|
||||
}
|
||||
if got == "" || got == "." || got == ".." {
|
||||
t.Fatalf("SafeUploadName(%q) = %q", name, got)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatalf("SafeUploadName(%q) = %q, want error", name, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user