summaryrefslogtreecommitdiff
path: root/internal/media/util.go
diff options
context:
space:
mode:
authorLibravatar kim <grufwub@gmail.com>2025-09-24 15:12:25 +0200
committerLibravatar kim <gruf@noreply.codeberg.org>2025-09-24 15:12:25 +0200
commit3db2d42247c5f88196ae7fb68b6bbec603bb7f26 (patch)
tree4fa7e793b230757219941f5b5a936a79b77eb000 /internal/media/util.go
parent[docs] Update tracing.md with up-to-date way of doing things (#4452) (diff)
downloadgotosocial-3db2d42247c5f88196ae7fb68b6bbec603bb7f26.tar.xz
[chore] ffmpeg webassembly fiddling (#4454)
This disables ffmpeg / ffprobe support on platforms where the wazero compiler is not available. The slowness introduced is hard to pindown for admins (and us!), so it's easier to just return an error message linking to docs on attempted media processing. It still allows the instance to run, just erroring if anything other than a jpeg is attempted to be processed. This should hopefully make it easier for users to notice these issues. Also further locks down our wazero 'allowFiles' fs and other media code to address: https://codeberg.org/superseriousbusiness/gotosocial/issues/4408 relates to: https://codeberg.org/superseriousbusiness/gotosocial/issues/4427 also relates to issues raised in #gotosocial-help on matrix closes https://codeberg.org/superseriousbusiness/gotosocial/issues/4408 Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4454 Co-authored-by: kim <grufwub@gmail.com> Co-committed-by: kim <grufwub@gmail.com>
Diffstat (limited to 'internal/media/util.go')
-rw-r--r--internal/media/util.go88
1 files changed, 59 insertions, 29 deletions
diff --git a/internal/media/util.go b/internal/media/util.go
index ea52b415b..d73206434 100644
--- a/internal/media/util.go
+++ b/internal/media/util.go
@@ -30,14 +30,41 @@ import (
"codeberg.org/gruf/go-iotools"
)
+// media processing tmpdir.
+var tmpdir = os.TempDir()
+
// file represents one file
// with the given flag and perms.
type file struct {
- abs string
+ abs string // absolute file path, including root
+ dir string // containing directory of abs
+ rel string // relative to root, i.e. trim_prefix(abs, dir)
flag int
perm os.FileMode
}
+// allowRead returns a new file{} for filepath permitted only to read.
+func allowRead(filepath string) file {
+ return newFile(filepath, os.O_RDONLY, 0)
+}
+
+// allowCreate returns a new file{} for filepath permitted to read / write / create.
+func allowCreate(filepath string) file {
+ return newFile(filepath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
+}
+
+// newFile returns a new instance of file{} for given path and open args.
+func newFile(filepath string, flag int, perms os.FileMode) file {
+ dir, rel := path.Split(filepath)
+ return file{
+ abs: filepath,
+ rel: rel,
+ dir: dir,
+ flag: flag,
+ perm: perms,
+ }
+}
+
// allowFiles implements fs.FS to allow
// access to a specified slice of files.
type allowFiles []file
@@ -45,36 +72,32 @@ type allowFiles []file
// Open implements fs.FS.
func (af allowFiles) Open(name string) (fs.File, error) {
for _, file := range af {
- var (
- abs = file.abs
- flag = file.flag
- perm = file.perm
- )
-
+ switch name {
// Allowed to open file
- // at absolute path.
- if name == file.abs {
- return os.OpenFile(abs, flag, perm)
- }
-
- // Check for other valid reads.
- thisDir, thisFile := path.Split(file.abs)
-
- // Allowed to read directory itself.
- if name == thisDir || name == "." {
- return os.OpenFile(thisDir, flag, perm)
- }
-
- // Allowed to read file
- // itself (at relative path).
- if name == thisFile {
- return os.OpenFile(abs, flag, perm)
+ // at absolute path, or
+ // relative as ffmpeg likes.
+ case file.abs, file.rel:
+ return os.OpenFile(file.abs, file.flag, file.perm)
+
+ // Ffmpeg likes to read containing
+ // dir as '.'. Allow RO access here.
+ case ".":
+ return openRead(file.dir)
}
}
-
return nil, os.ErrPermission
}
+// openRead opens the existing file at path for reads only.
+func openRead(path string) (*os.File, error) {
+ return os.OpenFile(path, os.O_RDONLY, 0)
+}
+
+// openWrite opens the (new!) file at path for read / writes.
+func openWrite(path string) (*os.File, error) {
+ return os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
+}
+
// getExtension splits file extension from path.
func getExtension(path string) string {
for i := len(path) - 1; i >= 0 && path[i] != '/'; i-- {
@@ -93,17 +116,24 @@ func getExtension(path string) string {
// chance that Linux's sendfile syscall can be utilised for optimal
// draining of data source to temporary file storage.
func drainToTmp(rc io.ReadCloser) (string, error) {
- defer rc.Close()
+ var tmp *os.File
+ var err error
+
+ // Close handles
+ // on func return.
+ defer func() {
+ tmp.Close()
+ rc.Close()
+ }()
// Open new temporary file.
- tmp, err := os.CreateTemp(
- os.TempDir(),
+ tmp, err = os.CreateTemp(
+ tmpdir,
"gotosocial-*",
)
if err != nil {
return "", err
}
- defer tmp.Close()
// Extract file path.
path := tmp.Name()