This commit is contained in:
npc0-hue
2026-08-26 09:56:43 +08:00
parent 2b4974b561
commit 8e02a316fa
93 changed files with 21749 additions and 0 deletions
+197
View File
@@ -0,0 +1,197 @@
package runtime
import (
"fmt"
"os"
"path/filepath"
"strings"
"browser.local/run/protocol"
)
const maxExecutionContentBytes = 64 * 1024
type WorkspaceResolver struct {
root string
}
func NewWorkspaceResolver(root string) WorkspaceResolver {
if strings.TrimSpace(root) == "" {
root = filepath.Join(".", ".run-workspace")
}
return WorkspaceResolver{root: root}
}
func (resolver WorkspaceResolver) Scope(serverInstanceID string, profileKey string) (string, error) {
if err := validateWorkspaceComponent(serverInstanceID, "serverInstanceId"); err != nil {
return "", err
}
if err := validateWorkspaceComponent(profileKey, "profileKey"); err != nil {
return "", err
}
root, err := filepath.Abs(resolver.root)
if err != nil {
return "", fmt.Errorf("resolve workspace root: %w", err)
}
if err := ensureDirectory(root); err != nil {
return "", fmt.Errorf("secure workspace root: %w", err)
}
instances := filepath.Join(root, "instances")
if err := ensureDirectory(instances); err != nil {
return "", fmt.Errorf("secure workspace instances: %w", err)
}
serverDir := filepath.Join(instances, serverInstanceID)
if err := ensureDirectory(serverDir); err != nil {
return "", fmt.Errorf("secure server workspace: %w", err)
}
scope := filepath.Join(serverDir, profileKey)
if err := ensureDirectory(scope); err != nil {
return "", fmt.Errorf("secure profile workspace: %w", err)
}
return scope, nil
}
func (resolver WorkspaceResolver) ExistingTarget(scope string, key string) (string, error) {
path, err := resolver.target(scope, key, false)
if err != nil {
return "", err
}
info, err := os.Lstat(path)
if err != nil {
return "", err
}
if info.Mode()&os.ModeSymlink != 0 || !info.Mode().IsRegular() {
return "", fmt.Errorf("target must be a regular file")
}
return path, nil
}
func (resolver WorkspaceResolver) ExistingDirectory(scope string, key string) (string, error) {
if strings.TrimSpace(scope) == "" || !protocol.ValidLogicalFileKey(key) || filepath.IsAbs(key) || strings.Contains(key, string(rune(92))) {
return "", fmt.Errorf("logical directory is unsafe")
}
cleanScope, err := filepath.Abs(scope)
if err != nil {
return "", err
}
root, err := filepath.Abs(resolver.root)
if err != nil {
return "", err
}
rel, err := filepath.Rel(root, cleanScope)
if err != nil || rel == "." || strings.HasPrefix(rel, "..") || filepath.IsAbs(rel) {
return "", fmt.Errorf("workspace scope escapes root")
}
current := cleanScope
for _, part := range strings.Split(filepath.ToSlash(key), "/") {
if part == "" || part == "." || part == ".." {
return "", fmt.Errorf("logical directory contains unsafe component")
}
current = filepath.Join(current, part)
info, statErr := os.Lstat(current)
if statErr != nil {
return "", statErr
}
if info.Mode()&os.ModeSymlink != 0 || !info.IsDir() {
return "", fmt.Errorf("logical directory is not a real directory")
}
}
return current, nil
}
func (resolver WorkspaceResolver) WritableTarget(scope string, key string) (string, string, error) {
if strings.HasPrefix(key, "actions/") || strings.HasPrefix(key, "state/") || key == "actions" || key == "state" {
return "", "", fmt.Errorf("target is reserved")
}
parts := strings.Split(filepath.ToSlash(key), "/")
parent := scope
for _, part := range parts[:len(parts)-1] {
parent = filepath.Join(parent, part)
if err := ensureDirectory(parent); err != nil {
return "", "", err
}
}
path, err := resolver.target(scope, key, true)
if err != nil {
return "", "", err
}
return path, filepath.Dir(path), nil
}
func (resolver WorkspaceResolver) target(scope string, key string, allowMissingFinal bool) (string, error) {
if strings.TrimSpace(scope) == "" {
return "", fmt.Errorf("workspace scope is invalid")
}
if !protocol.ValidLogicalFileKey(key) || filepath.IsAbs(key) || strings.Contains(key, `\`) {
return "", fmt.Errorf("logical key is unsafe")
}
cleanScope, err := filepath.Abs(scope)
if err != nil {
return "", err
}
root, err := filepath.Abs(resolver.root)
if err != nil {
return "", err
}
rel, err := filepath.Rel(root, cleanScope)
if err != nil || rel == "." || strings.HasPrefix(rel, "..") || filepath.IsAbs(rel) {
return "", fmt.Errorf("workspace scope escapes root")
}
parts := strings.Split(filepath.ToSlash(key), "/")
current := cleanScope
for index, part := range parts {
if part == "" || part == "." || part == ".." {
return "", fmt.Errorf("logical key contains unsafe component")
}
current = filepath.Join(current, part)
info, statErr := os.Lstat(current)
if statErr != nil {
if allowMissingFinal && index == len(parts)-1 && os.IsNotExist(statErr) {
return current, nil
}
return "", statErr
}
if info.Mode()&os.ModeSymlink != 0 {
return "", fmt.Errorf("logical key contains a symlink")
}
if index < len(parts)-1 && !info.IsDir() {
return "", fmt.Errorf("logical key parent is not a directory")
}
if index == len(parts)-1 && info.Mode()&os.ModeType != 0 {
return "", fmt.Errorf("target is a special file")
}
}
return current, nil
}
func ensureDirectory(path string) error {
if info, err := os.Lstat(path); err == nil {
if info.Mode()&os.ModeSymlink != 0 || !info.IsDir() {
return fmt.Errorf("path is not a real directory")
}
return os.Chmod(path, 0o700)
} else if !os.IsNotExist(err) {
return err
}
parent := filepath.Dir(path)
if parent != path {
if err := ensureDirectory(parent); err != nil {
return err
}
}
if err := os.Mkdir(path, 0o700); err != nil && !os.IsExist(err) {
return err
}
info, err := os.Lstat(path)
if err != nil || info.Mode()&os.ModeSymlink != 0 || !info.IsDir() {
return fmt.Errorf("created path is not a real directory")
}
return os.Chmod(path, 0o700)
}
func validateWorkspaceComponent(value string, field string) error {
if strings.TrimSpace(value) == "" || value != strings.TrimSpace(value) || value == "." || value == ".." || strings.ContainsAny(value, `/\`) || !protocol.ValidLogicalFileKey(value) {
return fmt.Errorf("%s is unsafe", field)
}
return nil
}