From 1c5ddcd20c684ae483923843f4979e13b420b574 Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Sun, 17 Mar 2024 14:46:05 -0600 Subject: [PATCH] server(filesystem): handle writing empty files Fixes https://github.com/pterodactyl/panel/issues/5038 Signed-off-by: Matthew Penner --- router/router_server_files.go | 3 ++- server/filesystem/filesystem.go | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/router/router_server_files.go b/router/router_server_files.go index e44afbe..09ad8cd 100644 --- a/router/router_server_files.go +++ b/router/router_server_files.go @@ -239,7 +239,8 @@ func postServerWriteFile(c *gin.Context) { return } - if c.Request.ContentLength < 1 { + // A content length of -1 means the actual length is unknown. + if c.Request.ContentLength == -1 { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ "error": "Missing Content-Length", }) diff --git a/server/filesystem/filesystem.go b/server/filesystem/filesystem.go index 8a7ae90..bfd49bc 100644 --- a/server/filesystem/filesystem.go +++ b/server/filesystem/filesystem.go @@ -166,17 +166,23 @@ func (fs *Filesystem) Write(p string, r io.Reader, newSize int64, mode ufs.FileM } defer file.Close() - // Do not use CopyBuffer here, it is wasteful as the file implements - // io.ReaderFrom, which causes it to not use the buffer anyways. - n, err := io.Copy(file, io.LimitReader(r, newSize)) + if newSize == 0 { + // Subtract the previous size of the file if the new size is 0. + fs.unixFS.Add(-currentSize) + } else { + // Do not use CopyBuffer here, it is wasteful as the file implements + // io.ReaderFrom, which causes it to not use the buffer anyways. + var n int64 + n, err = io.Copy(file, io.LimitReader(r, newSize)) - // Adjust the disk usage to account for the old size and the new size of the file. - fs.unixFS.Add(n - currentSize) + // Adjust the disk usage to account for the old size and the new size of the file. + fs.unixFS.Add(n - currentSize) + } if err := fs.chownFile(p); err != nil { return err } - // Return the error from io.Copy. + // Return any remaining error. return err }