diff --git a/chfs-ng/internal/api/server.go b/chfs-ng/internal/api/server.go index ed136af..b03fac0 100644 --- a/chfs-ng/internal/api/server.go +++ b/chfs-ng/internal/api/server.go @@ -302,10 +302,10 @@ func (s *Server) rename(w http.ResponseWriter, r *http.Request) { } if old != neu { if _, e := s.Store.Stat(neu); e == nil { - if e := checkDeleteTree(s.Store, a, neu); e != nil { - writeJSONError(w, http.StatusForbidden, "has no privilege") - return - } + // CHFS rename is create-only: an existing destination is rejected + // rather than overwritten, even when the caller has delete access. + writeJSONError(w, http.StatusBadRequest, "invalid parameter") + return } else if !os.IsNotExist(e) { http.Error(w, e.Error(), 500) return @@ -453,6 +453,13 @@ func (s *Server) newtext(w http.ResponseWriter, r *http.Request) { return } p := path.Join(dir, filename) + if _, e := s.Store.Stat(p); e == nil { + writeJSONError(w, http.StatusBadRequest, "invalid parameter") + return + } else if !os.IsNotExist(e) { + http.Error(w, e.Error(), 500) + return + } if !a.MaskFor(p).HasWrite() { writeJSONError(w, http.StatusForbidden, "has no privilege") return @@ -518,7 +525,15 @@ func (s *Server) upload(w http.ResponseWriter, r *http.Request) { http.Error(w, "invalid filename", 400) return } - if e := savePart(s.Store, path.Join(dir, name), h); e != nil { + target := path.Join(dir, name) + if _, e := s.Store.Stat(target); e == nil { + writeJSONError(w, http.StatusBadRequest, "invalid parameter") + return + } else if !os.IsNotExist(e) { + http.Error(w, e.Error(), 500) + return + } + if e := savePart(s.Store, target, h); e != nil { http.Error(w, e.Error(), 500) return } @@ -570,7 +585,15 @@ func (s *Server) upload2(w http.ResponseWriter, r *http.Request) { http.Error(w, "invalid filename", 400) return } - if err := savePart(s.Store, path.Join(dir, name), h); err != nil { + target := path.Join(dir, name) + if _, e := s.Store.Stat(target); e == nil { + writeJSONError(w, http.StatusBadRequest, "invalid parameter") + return + } else if !os.IsNotExist(e) { + http.Error(w, e.Error(), 500) + return + } + if err := savePart(s.Store, target, h); err != nil { http.Error(w, err.Error(), 500) return }