From 20859fa7d391cdcd5219c730f9c1042dfa0065bb Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 15 Aug 2023 15:05:42 +0200 Subject: [PATCH] fix!: add escaped abspath header Adds new 'abspath-encoded' header to MultiFileReader. New server sends both headers. New client prefers 'abspath-encoded' over 'abspath'. Old clients won't be compatible with new servers. --- CHANGELOG.md | 10 ++++++++++ files/multifilereader.go | 1 + files/multipartfile.go | 12 +++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3a41d83f..03084adb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,16 @@ The following emojis are used to highlight certain changes: ### Fixed +* 🛠 `MultiFileReader` has been updated with a new header with the encoded file + name instead of the plain filename, due to a regression found in + [`net/textproto`](https://github.com/golang/go/issues/60674). This only affects + files with binary characters in their name. By keeping the old header, we maximize + backwards compatibility. + | | New Client | Old Client | + |------------|------------|-------------| + | New Server | ✅ | ❌ | + | Old Server | ✅ | ✅ | + ### Security ## [v0.11.0] diff --git a/files/multifilereader.go b/files/multifilereader.go index af708dc7f..e2e07ab66 100644 --- a/files/multifilereader.go +++ b/files/multifilereader.go @@ -115,6 +115,7 @@ func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) { header.Set("Content-Type", contentType) if rf, ok := entry.Node().(FileInfo); ok { header.Set("abspath", rf.AbsPath()) + header.Set("abspath-encoded", url.QueryEscape(rf.AbsPath())) } _, err := mfr.mpWriter.CreatePart(header) diff --git a/files/multipartfile.go b/files/multipartfile.go index 27653982c..b5aab9620 100644 --- a/files/multipartfile.go +++ b/files/multipartfile.go @@ -100,9 +100,19 @@ func (w *multipartWalker) nextFile() (Node, error) { return NewLinkFile(string(out), nil), nil default: + var absPath string + if absPathEncoded := part.Header.Get("abspath-encoded"); absPathEncoded != "" { + absPath, err = url.QueryUnescape(absPathEncoded) + if err != nil { + return nil, err + } + } else { + absPath = part.Header.Get("abspath") + } + return &ReaderFile{ reader: part, - abspath: part.Header.Get("abspath"), + abspath: absPath, }, nil } }