mirror of
https://github.com/tw93/Mole.git
synced 2026-03-22 20:15:07 +00:00
fix(timeout): inherit helper state and pass checks
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@@ -165,10 +166,8 @@ func validatePath(path string) error {
|
|||||||
return fmt.Errorf("path contains null bytes")
|
return fmt.Errorf("path contains null bytes")
|
||||||
}
|
}
|
||||||
// Check for path traversal attempts (.. components).
|
// Check for path traversal attempts (.. components).
|
||||||
for _, component := range strings.Split(path, string(filepath.Separator)) {
|
if slices.Contains(strings.Split(path, string(filepath.Separator)), "..") {
|
||||||
if component == ".." {
|
return fmt.Errorf("path contains traversal components: %s", path)
|
||||||
return fmt.Errorf("path contains traversal components: %s", path)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -275,23 +275,22 @@ func getAPFSContainerFreeBytes(mountpoint string) (uint64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const key = "<key>APFSContainerFree</key>"
|
const key = "<key>APFSContainerFree</key>"
|
||||||
idx := strings.Index(out, key)
|
_, rest, found := strings.Cut(out, key)
|
||||||
if idx == -1 {
|
if !found {
|
||||||
return 0, fmt.Errorf("APFSContainerFree not found")
|
return 0, fmt.Errorf("APFSContainerFree not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
rest := out[idx+len(key):]
|
_, rest, found = strings.Cut(rest, "<integer>")
|
||||||
start := strings.Index(rest, "<integer>")
|
if !found {
|
||||||
if start == -1 {
|
|
||||||
return 0, fmt.Errorf("APFSContainerFree value not found")
|
return 0, fmt.Errorf("APFSContainerFree value not found")
|
||||||
}
|
}
|
||||||
rest = rest[start+len("<integer>"):]
|
|
||||||
end := strings.Index(rest, "</integer>")
|
value, _, found := strings.Cut(rest, "</integer>")
|
||||||
if end == -1 {
|
if !found {
|
||||||
return 0, fmt.Errorf("APFSContainerFree end tag not found")
|
return 0, fmt.Errorf("APFSContainerFree end tag not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
val, err := strconv.ParseUint(strings.TrimSpace(rest[:end]), 10, 64)
|
val, err := strconv.ParseUint(strings.TrimSpace(value), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("failed to parse APFSContainerFree: %v", err)
|
return 0, fmt.Errorf("failed to parse APFSContainerFree: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,11 @@ if [[ -z "${MO_TIMEOUT_INITIALIZED:-}" ]]; then
|
|||||||
echo "[TIMEOUT] Install coreutils for better reliability: brew install coreutils" >&2
|
echo "[TIMEOUT] Install coreutils for better reliability: brew install coreutils" >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Export so child processes inherit detected values and skip re-detection.
|
||||||
|
# Without this, children that inherit MO_TIMEOUT_INITIALIZED=1 skip the init
|
||||||
|
# block but have empty bin vars, forcing the slow shell fallback.
|
||||||
|
export MO_TIMEOUT_BIN
|
||||||
|
export MO_TIMEOUT_PERL_BIN
|
||||||
export MO_TIMEOUT_INITIALIZED=1
|
export MO_TIMEOUT_INITIALIZED=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -181,7 +186,10 @@ run_with_timeout() {
|
|||||||
"$@" &
|
"$@" &
|
||||||
local cmd_pid=$!
|
local cmd_pid=$!
|
||||||
|
|
||||||
# Start timeout killer in background
|
# Start timeout killer in background.
|
||||||
|
# Redirect all FDs to /dev/null so orphaned child processes (e.g. sleep $duration)
|
||||||
|
# do not inherit open file descriptors from the caller and block output pipes
|
||||||
|
# (notably bats output capture pipes that wait for all writers to close).
|
||||||
(
|
(
|
||||||
# Wait for timeout duration
|
# Wait for timeout duration
|
||||||
sleep "$duration"
|
sleep "$duration"
|
||||||
@@ -200,7 +208,7 @@ run_with_timeout() {
|
|||||||
kill -KILL -"$cmd_pid" 2> /dev/null || kill -KILL "$cmd_pid" 2> /dev/null || true
|
kill -KILL -"$cmd_pid" 2> /dev/null || kill -KILL "$cmd_pid" 2> /dev/null || true
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
) &
|
) < /dev/null > /dev/null 2>&1 &
|
||||||
local killer_pid=$!
|
local killer_pid=$!
|
||||||
|
|
||||||
# Wait for command to complete
|
# Wait for command to complete
|
||||||
|
|||||||
Reference in New Issue
Block a user