Fix #104338: Error performing BAT pack
Use RFC 2047 (aka MIME encoding) to send the original filename when uploading a file to the Shaman server. HTTP headers should be ASCII-only, and some systems use Latin-1 as fallback. That's not suitable in general, though, because almost all characters fall outside the Latin-1 range.
This commit is contained in:
parent
1f562b3cbc
commit
2e0e211b26
@ -17,6 +17,7 @@ bugs in actually-released versions.
|
||||
- Security updates of dependencies:
|
||||
- [GO-2024-3106: Stack exhaustion in Decoder.Decode in encoding/gob](https://pkg.go.dev/vuln/GO-2024-3106)
|
||||
- Fix bug where database foreign key constraints could be deactivated ([#104305](https://projects.blender.org/studio/flamenco/issues/104305)).
|
||||
- Fix bug when submitting a file with a non-ASCII name via Shaman ([#104338](https://projects.blender.org/studio/flamenco/issues/104338)).
|
||||
|
||||
## 3.5 - released 2024-04-16
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
"""BAT interface for sending files to the Manager via the Shaman API."""
|
||||
|
||||
import email.header
|
||||
import logging
|
||||
import random
|
||||
import platform
|
||||
@ -366,6 +367,7 @@ class Transferrer(submodules.transfer.FileTransferer): # type: ignore
|
||||
)
|
||||
|
||||
local_filepath = self._rel_to_local_path[file_spec.path]
|
||||
filename_header = _encode_original_filename_header(file_spec.path)
|
||||
try:
|
||||
with local_filepath.open("rb") as file_reader:
|
||||
self.shaman_api.shaman_file_store(
|
||||
@ -373,7 +375,7 @@ class Transferrer(submodules.transfer.FileTransferer): # type: ignore
|
||||
filesize=file_spec.size,
|
||||
body=file_reader,
|
||||
x_shaman_can_defer_upload=can_defer,
|
||||
x_shaman_original_filename=file_spec.path,
|
||||
x_shaman_original_filename=filename_header,
|
||||
)
|
||||
except ApiException as ex:
|
||||
if ex.status == 425:
|
||||
@ -527,3 +529,16 @@ def _root_path_strip(path: PurePath) -> PurePosixPath:
|
||||
if path.is_absolute():
|
||||
return PurePosixPath(*path.parts[1:])
|
||||
return PurePosixPath(path)
|
||||
|
||||
|
||||
def _encode_original_filename_header(filename: str) -> str:
|
||||
"""Encode the 'original filename' as valid HTTP Header.
|
||||
|
||||
See the specs for the X-Shaman-Original-Filename header in the OpenAPI
|
||||
operation `shamanFileStore`, defined in flamenco-openapi.yaml.
|
||||
"""
|
||||
|
||||
# This is a no-op when the filename is already in ASCII.
|
||||
fake_header = email.header.Header()
|
||||
fake_header.append(filename, charset="utf-8")
|
||||
return fake_header.encode()
|
||||
|
@ -3,6 +3,7 @@ package api_impl
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import (
|
||||
"mime"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
@ -110,8 +111,22 @@ func (f *Flamenco) ShamanFileStore(e echo.Context, checksum string, filesize int
|
||||
canDefer = *params.XShamanCanDeferUpload
|
||||
logCtx = logCtx.Bool("canDefer", canDefer)
|
||||
}
|
||||
|
||||
if params.XShamanOriginalFilename != nil {
|
||||
origFilename = *params.XShamanOriginalFilename
|
||||
rawHeadervalue := *params.XShamanOriginalFilename
|
||||
decoder := mime.WordDecoder{}
|
||||
|
||||
var err error // origFilename has to be used from the outer scope.
|
||||
origFilename, err = decoder.DecodeHeader(rawHeadervalue)
|
||||
if err != nil {
|
||||
logger := logCtx.Logger()
|
||||
logger.Error().
|
||||
Str("headerValue", rawHeadervalue).
|
||||
Err(err).
|
||||
Msg("shaman: received invalid X-Shaman-Original-Filename header")
|
||||
return sendAPIError(e, http.StatusBadRequest, "invalid X-Shaman-Original-Filename header: %q", rawHeadervalue)
|
||||
}
|
||||
|
||||
logCtx = logCtx.Str("originalFilename", origFilename)
|
||||
}
|
||||
logger := logCtx.Logger()
|
||||
|
Loading…
x
Reference in New Issue
Block a user