(doer *User, opts UploadRepoFileOptions)
| 548 | } |
| 549 | |
| 550 | func (r *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions) error { |
| 551 | if len(opts.Files) == 0 { |
| 552 | return nil |
| 553 | } |
| 554 | |
| 555 | // 🚨 SECURITY: Prevent uploading files into the ".git" directory. |
| 556 | if isRepositoryGitPath(opts.TreePath) { |
| 557 | return errors.Errorf("bad tree path %q", opts.TreePath) |
| 558 | } |
| 559 | |
| 560 | uploads, err := GetUploadsByUUIDs(opts.Files) |
| 561 | if err != nil { |
| 562 | return errors.Newf("get uploads by UUIDs[%v]: %v", opts.Files, err) |
| 563 | } |
| 564 | |
| 565 | repoWorkingPool.CheckIn(com.ToStr(r.ID)) |
| 566 | defer repoWorkingPool.CheckOut(com.ToStr(r.ID)) |
| 567 | |
| 568 | if err = r.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil { |
| 569 | return errors.Newf("discard local r branch[%s] changes: %v", opts.OldBranch, err) |
| 570 | } else if err = r.UpdateLocalCopyBranch(opts.OldBranch); err != nil { |
| 571 | return errors.Newf("update local copy branch[%s]: %v", opts.OldBranch, err) |
| 572 | } |
| 573 | |
| 574 | if opts.OldBranch != opts.NewBranch { |
| 575 | if err = r.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil { |
| 576 | return errors.Newf("checkout new branch[%s] from old branch[%s]: %v", opts.NewBranch, opts.OldBranch, err) |
| 577 | } |
| 578 | } |
| 579 | |
| 580 | localPath := r.LocalCopyPath() |
| 581 | dirPath := path.Join(localPath, opts.TreePath) |
| 582 | if err = os.MkdirAll(dirPath, os.ModePerm); err != nil { |
| 583 | return err |
| 584 | } |
| 585 | |
| 586 | // Copy uploaded files into repository |
| 587 | for _, upload := range uploads { |
| 588 | tmpPath := upload.LocalPath() |
| 589 | if !osutil.IsFile(tmpPath) { |
| 590 | continue |
| 591 | } |
| 592 | |
| 593 | // 🚨 SECURITY: Prevent path traversal. |
| 594 | upload.Name = pathutil.Clean(upload.Name) |
| 595 | |
| 596 | // 🚨 SECURITY: Prevent uploading files into the ".git" directory. |
| 597 | if isRepositoryGitPath(upload.Name) { |
| 598 | continue |
| 599 | } |
| 600 | |
| 601 | targetPath := path.Join(dirPath, upload.Name) |
| 602 | |
| 603 | // 🚨 SECURITY: Prevent touching files in surprising places, reject operations |
| 604 | // that involve symlinks. |
| 605 | if hasSymlinkInPath(localPath, path.Join(opts.TreePath, upload.Name)) { |
| 606 | return errors.Newf("cannot overwrite symbolic link: %s", upload.Name) |
| 607 | } |
no test coverage detected