Skip to content

zsh: __gvm_munge_path breaks PATH entries containing spaces, which can cascade into _encode/hexdump failures #544

Description

@jason7758

Issue 标题建议

zsh: __gvm_munge_path breaks PATH entries containing spaces, which can cascade into _encode/hexdump failures

Issue 正文建议

Summary

zsh 环境下,如果现有 PATH 中包含带空格的目录(例如 macOS 上常见的 Application Support 路径),gvm__gvm_munge_path() 会把这些条目错误拆分,生成损坏的 PATH
这会进一步导致 shell 启动异常,以及后续脚本依赖的命令路径解析失败。

我本地遇到的表现包括:

  • PATH 中的带空格目录被拆成类似 Application:Support/...
  • 某些工具启动失败
  • gvm 内部 _encode() 在特定情况下报:
_encode:25: command not found: -e

Environment

  • OS: macOS
  • Shell: zsh
  • gvm: current master

Reproduction

  1. 准备一个包含空格路径的 PATH,例如:
export PATH="/tmp/foo:/Users/example/Library/Application Support/demo/bin:/usr/bin:/bin"
  1. 加载 gvm
source "$HOME/.gvm/scripts/gvm"
  1. 观察 PATH
printf '%s\n' "$PATH"

Actual behavior

PATH 中带空格的条目被错误拆分。例如:

/Users/example/Library/Application:Support/demo/bin

而不是保留为单个合法路径条目:

/Users/example/Library/Application Support/demo/bin

Expected behavior

gvm 应只按 : 分隔 PATH,而不应把空格当作分隔符。
带空格的合法目录条目应完整保留。

Root cause

当前 scripts/function/munge_path 中这行代码会同时按 : 和空格拆分:

IFS=': ' path_in_ary=( $(printf "%s" "${path_in}") ) IFS="$defaultIFS"

这会直接破坏 macOS 上含空格的 PATH 条目。

此外,scripts/function/_bash_pseudo_hash_encode() 依赖:

hex="$(echo -n "$__char" | $HEXDUMP_PATH -e '1 1 "!%02x"')"

如果上游环境已被破坏,或 HEXDUMP_PATH 为空,就可能退化成把 -e 当作命令执行,从而出现:

command not found: -e

Suggested fix

至少应先修复 __gvm_munge_path()PATH 的拆分方式,避免把空格作为分隔符。

一个直接方向是只按 : 分割,而不是:

IFS=': '

同时,_encode()HEXDUMP_PATH 也可以增加健壮性保护,避免空变量时把 -e 当作命令名执行。

Additional note

这个问题在 macOS 上更容易出现,因为很多应用注入到 PATH 的目录本身就包含空格。


PR 标题建议

Fix PATH splitting in __gvm_munge_path when entries contain spaces

PR 描述建议

Summary

这个 PR 修复 __gvm_munge_path()zsh / macOS 场景下对带空格 PATH 条目的错误拆分。

Problem

当前实现使用:

IFS=': ' path_in_ary=( $(printf "%s" "${path_in}") ) IFS="$defaultIFS"

这会把空格也当成分隔符,导致合法的 PATH 条目被拆坏。
在 macOS 上,这会影响包含 Application Support 等路径的环境。

损坏的 PATH 还可能连锁影响后续命令查找与 shell 初始化。

Change

  • 仅按 : 分割 PATH
  • 保留包含空格的单个路径条目
  • 避免 gvm 在加载时破坏现有 shell 环境

Why this is safe

  • PATH 的标准分隔符本来就是 :
  • 空格是合法的路径字符,不应被当作额外分隔符
  • 这个改动只修正分割逻辑,不改变 gvm.gvm / .rvm 条目的重排语义

Validation

可通过以下场景验证:

  1. PATH 不含空格目录时,行为与当前版本一致
  2. PATH 含空格目录时,目录条目保持完整
  3. source ~/.gvm/scripts/gvm 后,PATH 不再出现被拆成 Application:Support/... 的情况

Optional follow-up

后续还可以补一个防御性修复:
_encode() 中对 HEXDUMP_PATH 为空的情况做显式检查,避免退化成执行 -e


可附带的最小修复思路

如果想在 PR 里顺手给出实现方向,可以附上这段说明:

# current
IFS=': ' path_in_ary=( $(printf "%s" "${path_in}") ) IFS="$defaultIFS"

# intended direction
IFS=':' path_in_ary=( ${(s/:/)path_in} )

如果需要同时兼容 bash / zsh,实现方式可能还要再做一层兼容性处理;
但核心原则是不应再按空格拆分 PATH

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions