From 980fe6b33c02a1e997a3e24f7061bacf46f8b76a Mon Sep 17 00:00:00 2001 From: Colin Date: Sun, 12 May 2024 22:15:34 +0000 Subject: [PATCH] sane-sandboxed: use `local` where applicable --- pkgs/additional/sane-sandboxed/sane-sandboxed | 221 +++++++++--------- 1 file changed, 106 insertions(+), 115 deletions(-) diff --git a/pkgs/additional/sane-sandboxed/sane-sandboxed b/pkgs/additional/sane-sandboxed/sane-sandboxed index 917be60a..40bf0931 100644 --- a/pkgs/additional/sane-sandboxed/sane-sandboxed +++ b/pkgs/additional/sane-sandboxed/sane-sandboxed @@ -154,39 +154,39 @@ relativeTo() { # chomps trailing slashes. # does not resolve symlinks, nor check for existence of any component of the path. normPath() { - _npOut="$1" - _npUnparsed="$2" - _npComps=() - while [ -n "$_npUnparsed" ]; do + local npOut="$1" + local npUnparsed="$2" + local npComps=() + while [ -n "$npUnparsed" ]; do # chomp leading `/` - _npUnparsed="${_npUnparsed:1}" + npUnparsed="${npUnparsed:1}" # split into - # in the case of `//`, or more, _npThisComp is empty, - # and we push nothing to _npComps, + # in the case of `//`, or more, npThisComp is empty, + # and we push nothing to npComps, # but we're guaranteed to make progress. - _npThisComp="${_npUnparsed%%/*}" - _npThisLen="${#_npThisComp}" - _npUnparsed="${_npUnparsed:$_npThisLen}" - if [ "$_npThisComp" = ".." ]; then + npThisComp="${npUnparsed%%/*}" + npThisLen="${#npThisComp}" + npUnparsed="${npUnparsed:$npThisLen}" + if [ "$npThisComp" = ".." ]; then # "go up" path component => delete the leaf dir (if any) - if [ ${#_npComps[@]} -ne 0 ]; then - unset _npComps[-1] + if [ ${#npComps[@]} -ne 0 ]; then + unset npComps[-1] fi - elif [ "$_npThisComp" != "." ] && [ -n "$_npThisComp" ]; then + elif [ "$npThisComp" != "." ] && [ -n "$npThisComp" ]; then # normal, non-empty path component => append it - _npComps+=("$_npThisComp") + npComps+=("$npThisComp") fi done # join the components - if [ ${#_npComps[@]} -eq 0 ]; then - declare -g "$_npOut"="/" + if [ ${#npComps[@]} -eq 0 ]; then + declare -g "$npOut"="/" else - _npJoined= - for _npComp in "${_npComps[@]}"; do - _npJoined="$_npJoined/$_npComp" + local npJoined= + for npComp in "${npComps[@]}"; do + npJoined="$npJoined/$npComp" done - declare -g "$_npOut"="$_npJoined" + declare -g "$npOut"="$npJoined" fi } @@ -263,21 +263,21 @@ loadProfileByPath() { } tryLoadProfileByName() { - _profile="$1" - if [ "${_profile:0:1}" = "/" ]; then + local profile="$1" + if [ "${profile:0:1}" = "/" ]; then # absolute path to profile. # consider it an error if it doesn't exist. # in general, prefer to use `--sane-sandbox-profile-dir` and specify the profile by name. # doing so maximizes compatibility with anything else that uses the name, like firejail. - loadProfileByPath "$_profile" + loadProfileByPath "$profile" else - profilesNamed+=("$_profile") + profilesNamed+=("$profile") - for _profileDir in "${profileDirs[@]}"; do - _profilePath="$_profileDir/$_profile.profile" - debug "try profile at path: '$_profilePath'" - if [ -f "$_profilePath" ]; then - loadProfileByPath "$_profilePath" + for profileDir in "${profileDirs[@]}"; do + local profilePath="$profileDir/$profile.profile" + debug "try profile at path: '$profilePath'" + if [ -f "$profilePath" ]; then + loadProfileByPath "$profilePath" break fi done @@ -291,55 +291,54 @@ initDefaultProfileDirs() { } # subroutine of `tryArgAsPath` for after the arg has been converted into a valid (but possibly not existing) path. -# adds an entry to `cliPathArgs` and evals `true` on success; +# adds an entry to `paths` and evals `true` on success; # evals `false` if the path couldn't be added, for any reason. -cliPathArgs=() tryPath() { - _path="$1" - _how="$2" + local path="$1" + local how="$2" - if [ "$_how" = "existing" ]; then + if [ "$how" = "existing" ]; then # the caller wants to access either a file, or a directory (possibly a symlink to such a thing) - if [ -e "$_path" ]; then - cliPathArgs+=("$(relativeTo "$PWD" "$_path")") + if [ -e "$path" ]; then + paths+=("$(relativeTo "$PWD" "$path")") true fi false - elif [ "$_how" = "existingFile" ]; then + elif [ "$how" = "existingFile" ]; then # the caller wants to access a file, and explicitly *not* a directory (though it could be a symlink *to a file*) - if [ -f "$_path" ]; then - cliPathArgs+=("$(relativeTo "$PWD" "$_path")") + if [ -f "$path" ]; then + paths+=("$(relativeTo "$PWD" "$path")") true fi false - elif [ "$_how" = "parent" ]; then + elif [ "$how" = "parent" ]; then # the caller wants access to the entire directory containing this directory regardless of the file's existence. - parent _tryPathParent "$_path" + parent _tryPathParent "$path" tryPath "$_tryPathParent" "existing" - elif [ "$_how" = "existingOrParent" ]; then + elif [ "$how" = "existingOrParent" ]; then # the caller wants access to the path, or write access to the parent directory so it may create the path if it doesn't exist. - tryPath "$_path" "existing" || tryPath "$_path" "parent" - elif [ "$_how" = "existingFileOrParent" ]; then + tryPath "$path" "existing" || tryPath "$path" "parent" + elif [ "$how" = "existingFileOrParent" ]; then # the caller wants access to the file, or write access to the parent directory so it may create the file if it doesn't exist. - tryPath "$_path" "existingFile" || tryPath "$_path" "parent" + tryPath "$path" "existingFile" || tryPath "$path" "parent" fi } -# if the argument looks path-like, then add it to cliPathArgs. +# if the argument looks path-like, then add it to paths. # this function ingests absolute, relative, or file:///-type URIs. -# but it converts any such path into an absolute path before adding it to cliPathArgs. +# but it converts any such path into an absolute path before adding it to paths. tryArgAsPath() { - _arg="$1" - _how="$2" + local arg="$1" + local how="$2" _path= - if [ "${_arg:0:1}" = "/" ]; then + if [ "${arg:0:1}" = "/" ]; then # absolute path _path="$_arg" - elif [ "${_arg:0:8}" = "file:///" ]; then + elif [ "${arg:0:8}" = "file:///" ]; then # URI to an absolute path which is presumably on this vfs # commonly found when xdg-open/mimeo passes a path on to an application # if URIs to relative paths exist, this implementation doesn't support them - urldecode _path "${_arg:7}" + urldecode _path "${arg:7}" elif [ "${_path:0:1}" = "-" ]; then # 99% chance it's a CLI argument. if not, use `./-<...>` return @@ -348,7 +347,7 @@ tryArgAsPath() { _path="$PWD/$_arg" fi - tryPath "$_path" "$_how" + tryPath "$_path" "$how" } @@ -358,9 +357,9 @@ tryArgAsPath() { parseArgsExtra=() parseArgs() { while [ "$#" -ne 0 ]; do - _arg="$1" + local arg="$1" shift - case "$_arg" in + case "$arg" in (--) # rest of args are for the CLI, and not for us. # consider two cases: @@ -410,9 +409,9 @@ parseArgs() { shift ;; (--sane-sandbox-cap) - _cap="$1" + local cap="$1" shift - capabilities+=("$_cap") + capabilities+=("$cap") ;; (--sane-sandbox-portal) # instruct glib/gtk apps to perform actions such as opening external files via dbus calls to org.freedesktop.portal.*. @@ -427,41 +426,40 @@ parseArgs() { ;; (--sane-sandbox-dns) # N.B.: these named temporary variables ensure that "set -x" causes $1 to be printed - _dns="$1" + local dns="$1" shift - dns+=("$_dns") + dns+=("$dns") ;; (--sane-sandbox-firejail-arg) - _fjFlag="$1" + local fjFlag="$1" shift - firejailFlags+=("$_fjFlag") + firejailFlags+=("$fjFlag") ;; (--sane-sandbox-bwrap-arg) - _bwrapFlag="$1" + local bwrapFlag="$1" shift - bwrapFlags+=("$_bwrapFlag") + bwrapFlags+=("$bwrapFlag") ;; (--sane-sandbox-net) net="$1" shift ;; (--sane-sandbox-keep-namespace) - _namespace="$1" + local namespace="$1" shift - if [ "$_namespace" = all ]; then + if [ "$namespace" = all ]; then keepNamespace+=("cgroup" "ipc" "pid" "uts") else - keepNamespace+=("$_namespace") + keepNamespace+=("$namespace") fi ;; (--sane-sandbox-path) - _path="$1" + local path="$1" shift - paths+=("$_path") + paths+=("$(relativeTo "$PWD" "$path")") ;; (--sane-sandbox-add-pwd) - _path="$PWD" - paths+=("$_path") + paths+=("$PWD") ;; (--sane-sandbox-profile) # load the profile *immediately*, inline. @@ -472,12 +470,12 @@ parseArgs() { (--sane-sandbox-profile-dir) # add another directory in which to search for profiles, # and give it *greater* precedence than the existing search directories (i.e. override the default profile) - _dir="$1" + local dir="$1" shift - profileDirs=("$_dir" "${profileDirs[@]}") + profileDirs=("$dir" "${profileDirs[@]}") ;; (*) - parseArgsExtra+=("$_arg") + parseArgsExtra+=("$arg") ;; esac done @@ -511,12 +509,12 @@ firejailIngestProfile() { firejailName="$1" fi if [ -z "$firejailProfile" ]; then - _fjProfileDirs=(@firejailProfileDirs@) - for _fjProfileDir in "${_fjProfileDirs[@]}"; do - _fjProfile="$_fjProfileDir/$1.profile" - debug "try firejail profile at path: '$_fjProfile'" - if [ -f "$_fjProfile" ]; then - firejailProfile="$_fjProfile" + local fjProfileDirs=(@firejailProfileDirs@) + for fjProfileDir in "${fjProfileDirs[@]}"; do + local fjProfile="$fjProfileDir/$1.profile" + debug "try firejail profile at path: '$fjProfile'" + if [ -f "$fjProfile" ]; then + firejailProfile="$fjProfile" fi done fi @@ -564,8 +562,8 @@ bwrapIngestPath() { # may be possible to place ever mount in a subdir, and mount the super dir? # or maybe configure remote mounts to somehow never hang. # test -r "$1" && bwrapFlags+=("--dev-bind-try" "$1" "$1") - local target="$(readlink "$1")" - if [ -n "$target" ]; then + if [ -L "$1" ]; then + local target="$(readlink "$1")" bwrapFlags+=("--symlink" "$target" "$1") else bwrapFlags+=("--dev-bind-try" "$1" "$1") @@ -783,13 +781,8 @@ noneGetCli() { # so allow access to it. maybeAutodetectPaths() { if [ -n "$autodetect" ]; then - for _arg in "${cliArgs[@]:1}"; do - tryArgAsPath "$_arg" "$autodetect" - done - for _path in "${cliPathArgs[@]}"; do - # TODO: might want to also mount the directory *above* this file, - # to access e.g. adjacent album art in the media's folder. - paths+=("$_path") + for arg in "${cliArgs[@]:1}"; do + tryArgAsPath "$arg" "$autodetect" done fi } @@ -800,16 +793,14 @@ maybeAutodetectPaths() { # for more sophisticated (i.e. complex) backends like firejail, this may break subpaths which were blacklisted earlier. canonicalizePaths() { # remove '//' and simplify '.', '..' paths, into canonical absolute logical paths. - local normPaths=() for path in "${paths[@]}"; do normPath _canonPath "$path" - normPaths+=("$_canonPath") + paths+=("$_canonPath") done - paths=("${normPaths[@]}") } expandLink() { - local target="$(readlink "$1")" - if [ -n "$target" ]; then + if [ -L "$1" ]; then + local target="$(readlink "$1")" # make absolute target="$(relativeTo "$(dirname "$1")" "$target")" # add + expand the symlink further, but take care to avoid infinite recursion @@ -822,32 +813,32 @@ expandLink() { } ### expand `paths` until it contains no symlinks whose target isn't also in `paths` expandLinks() { - for _path in "${paths[@]}"; do - expandLink "$_path" + for path in "${paths[@]}"; do + expandLink "$path" done } removeSubpaths() { # remove subpaths, but the result might include duplicates. local toplevelPaths=() - for _path in "${paths[@]}"; do + for path in "${paths[@]}"; do local isSubpath= - for _other in "${paths[@]}"; do - if [[ "$_path" =~ ^$_other/.* ]] || [ "$_other" = "/" ] && [ "$_path" != "/" ]; then - # N.B.: $_path lacks a trailing slash, so this never matches self. - # UNLESS $_path or $_other is exactly `/`, which we special-case. + for other in "${paths[@]}"; do + if [[ "$path" =~ ^$other/.* ]] || [ "$other" = "/" ] && [ "$path" != "/" ]; then + # N.B.: $path lacks a trailing slash, so this never matches self. + # UNLESS $path or $other is exactly `/`, which we special-case. isSubpath=1 fi done if [ -z "$isSubpath" ]; then - toplevelPaths+=("$_path") + toplevelPaths+=("$path") fi done # remove duplicated paths. local canonicalizedPaths=() - for _path in "${toplevelPaths[@]}"; do - if ! $(contains "$_path" "${canonicalizedPaths[@]}"); then - canonicalizedPaths+=("$_path") + for path in "${toplevelPaths[@]}"; do + if ! $(contains "$path" "${canonicalizedPaths[@]}"); then + canonicalizedPaths+=("$path") fi done paths=("${canonicalizedPaths[@]}") @@ -873,28 +864,28 @@ parseArgsAndEnvironment() { ### convert generic args into sandbox-specific args # order matters: for firejail, early args override the later --profile args ingestForBackend() { - for _path in "${paths[@]}"; do - "$method"IngestPath "$_path" + for path in "${paths[@]}"; do + "$method"IngestPath "$path" done - for _cap in "${capabilities[@]}"; do - "$method"IngestCapability "$_cap" + for cap in "${capabilities[@]}"; do + "$method"IngestCapability "$cap" done if [ -n "$net" ]; then "$method"IngestNet "$net" fi - for _addr in "${dns[@]}"; do - "$method"IngestDns "$_addr" + for addr in "${dns[@]}"; do + "$method"IngestDns "$addr" done - for _ns in "${keepNamespace[@]}"; do - "$method"IngestKeepNamespace "$_ns" + for ns in "${keepNamespace[@]}"; do + "$method"IngestKeepNamespace "$ns" done - for _prof in "${profilesNamed[@]}"; do - "$method"IngestProfile "$_prof" + for prof in "${profilesNamed[@]}"; do + "$method"IngestProfile "$prof" done }