Smail/backend/hooks/bundle.go
smail f732a255ce
Some checks are pending
Security Checks / security (push) Waiting to run
拆分内置插件文件的跨平台安全创建
2026-09-22 02:38:11 +08:00

53 lines
1.3 KiB
Go

package hooks
import (
"errors"
"io/fs"
"os"
"path/filepath"
"sync"
)
var bundledPlugins fs.FS
var bundledRoot string
var bundleMu sync.Mutex
// SetBundledPlugins 注入编译时封装的插件;插件仍作为独立进程运行,不放宽生产隔离。
func SetBundledPlugins(files fs.FS) {
bundledPlugins = files
}
func pluginRoot() (string, error) {
bundleMu.Lock()
defer bundleMu.Unlock()
if bundledPlugins == nil {
return filepath.Abs("./plugins")
}
if bundledRoot != "" {
return bundledRoot, nil
}
entries, err := fs.ReadDir(bundledPlugins, ".")
if err != nil || len(entries) != 3 {
return "", errors.New("内置插件包不完整")
}
// 操作系统临时沙箱不属于部署文件,避免向 config 或 data 解包可执行程序。
root, err := os.MkdirTemp("", "smail-bundled-")
if err != nil {
return "", err
}
for _, entry := range entries {
if entry.IsDir() || !entry.Type().IsRegular() {
return "", errors.New("内置插件包含有无效文件")
}
data, err := fs.ReadFile(bundledPlugins, entry.Name())
if err != nil || len(data) == 0 {
return "", errors.New("内置插件内容不可用")
}
if err := writeBundledPlugin(filepath.Join(root, entry.Name()), data); err != nil {
return "", err
}
}
bundledRoot = root
return root, nil
}