mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
* feat: Sandbox implementation with seatbelt * refactor: Remove concept of PM_CACHE * fix: Misc fixes * refactor: Sandbox for separation of boundaries * fix: Apply API * fix: Add support for sandbox cleanup * test: Add variable interpolation test * fix: Misc cleanup fixes * chore: Cleanup sandbox registry * chore: Cleanup sandbox policy * chore: Cleanup sandbox * fix: Misc cleanup fixes * fix: Remove violation mode * fix: Update config template * chore: Go mod cleanup * fix: Handle the case when package manager policy is explicitly disabled * fix: Sandbox executor * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Abhisek Datta <abhisek.datta@gmail.com> * test: Remove unused var * test: Add test for seatbelt sandbox driver * fix: Sandbox profile loader from file should use path for caching * test: Add policy test * feat: Add support for config templates * fix: Seatbelt translator handle glob * fix: Merge conflicts * fix: Fix sandbox policy generator for MacOS min permissions * fix: Sandbox path handling bugs * fix: Deny read to dangerous directories * fix: Deny read to dangerous directories * add sandbox e2e (#112) * fix: Sandbox E2E test * fix: Code review fixes * fix: Code review fixes * doc: Add sandbox debugging guide * doc: Update sandbox doc * docs: Add sandbox usage doc * fix: Use better error for sandbox without policy * fix: Add sandbox for npx * fix: Enable PTY for npm --------- Signed-off-by: Abhisek Datta <abhisek.datta@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Sahil Bansal <bansalsahil315@gmail.com>
95 lines
3.4 KiB
Go
95 lines
3.4 KiB
Go
package util
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// GlobToRegex converts a glob pattern to a Seatbelt-compatible regular expression.
|
|
//
|
|
// This implements gitignore-style pattern matching to match the behavior used
|
|
// in filesystem permission systems.
|
|
//
|
|
// Supported patterns:
|
|
// - * matches any characters except / (e.g., *.ts matches foo.ts but not foo/bar.ts)
|
|
// - ** matches any characters including / (e.g., src/**/*.ts matches all .ts files in src/)
|
|
// - ? matches any single character except / (e.g., file?.txt matches file1.txt)
|
|
// - [abc] matches any character in the set (e.g., file[0-9].txt matches file3.txt)
|
|
//
|
|
// Note: This is designed for macOS sandbox (regex ...) syntax. The resulting regex
|
|
// will be used in sandbox profiles like: (deny file-write* (regex "pattern"))
|
|
//
|
|
// Examples:
|
|
// - "/path/to/*.txt" -> "^/path/to/[^/]*\\.txt$"
|
|
// - "/path/**/file" -> "^/path/(.*/)?file$"
|
|
// - "/tmp/file?.log" -> "^/tmp/file[^/]\\.log$"
|
|
func GlobToRegex(globPattern string) string {
|
|
result := normalizeGlobPathSeparator(globPattern)
|
|
|
|
// Escape regex special characters (except glob chars * ? [ ])
|
|
// We need to escape: . ^ $ + { } ( ) | \
|
|
result = escapeRegexChars(result)
|
|
|
|
// Escape unclosed brackets (no matching ])
|
|
// This handles edge cases like "[abc" which should be treated literally
|
|
result = escapeUnclosedBrackets(result)
|
|
|
|
// Convert glob patterns to regex (order matters - ** before *)
|
|
// Use placeholders to avoid double-conversion
|
|
|
|
// 1. Handle **/ (globstar with slash)
|
|
result = strings.ReplaceAll(result, "**/", "__GLOBSTAR_SLASH__")
|
|
|
|
// 2. Handle ** (globstar standalone)
|
|
result = strings.ReplaceAll(result, "**", "__GLOBSTAR__")
|
|
|
|
// 3. Handle * (wildcard)
|
|
result = strings.ReplaceAll(result, "*", "[^/]*")
|
|
|
|
// 4. Handle ? (single char wildcard)
|
|
result = strings.ReplaceAll(result, "?", "[^/]")
|
|
|
|
// 5. Restore placeholders
|
|
result = strings.ReplaceAll(result, "__GLOBSTAR_SLASH__", "(.*/)?")
|
|
result = strings.ReplaceAll(result, "__GLOBSTAR__", ".*")
|
|
|
|
// Add anchors for exact matching
|
|
return "^" + result + "$"
|
|
}
|
|
|
|
// escapeRegexChars escapes regex special characters except glob wildcards.
|
|
// Escapes: . ^ $ + { } ( ) |
|
|
// Preserves: * ? [ ] \
|
|
// Note: We don't escape backslash because it shouldn't appear in file path glob patterns
|
|
func escapeRegexChars(s string) string {
|
|
// Characters that need escaping in regex (excluding glob chars)
|
|
// We don't include backslash here because:
|
|
// 1. File paths on Unix don't contain backslashes
|
|
// 2. We use backslash to escape regex chars, so escaping backslash would double them
|
|
specialChars := []string{".", "^", "$", "+", "{", "}", "(", ")", "|"}
|
|
|
|
result := s
|
|
for _, char := range specialChars {
|
|
result = strings.ReplaceAll(result, char, "\\"+char)
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// normalizeGlobPathSeparator normalizes the path separator for a glob pattern.
|
|
// This is to keep options open to normalize the path separator when we support Windows.
|
|
// Particularly for Windows, the path separator is '\\' instead of '/'. We will normalize
|
|
// the path separator to '/' for consistency.
|
|
func normalizeGlobPathSeparator(s string) string {
|
|
return s
|
|
}
|
|
|
|
var escapeUnclosedBracketsRegex = regexp.MustCompile(`\[([^\]]*?)$`)
|
|
|
|
// escapeUnclosedBrackets escapes bracket expressions that don't have a closing bracket.
|
|
// Example: "[abc" -> "\[abc"
|
|
func escapeUnclosedBrackets(s string) string {
|
|
// Find all opening brackets that don't have a closing bracket
|
|
return escapeUnclosedBracketsRegex.ReplaceAllString(s, `\[$1`)
|
|
}
|