From 195b9fe940cf787c80215d5fb14dbad6127b1ef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=98=E5=85=B8?= Date: Sat, 8 Aug 2026 20:35:35 +0300 Subject: [PATCH] version-file: Fix infinite loop for relative paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit find_local_version_file reduces its target with ${root%/*}, but that leaves a slash-less relative argument such as "." unchanged, leading to an infinite loop Signed-off-by: 付典 --- libexec/pyenv-version-file | 3 +++ test/version-file.bats | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/libexec/pyenv-version-file b/libexec/pyenv-version-file index 91d8b0d3..8b1fe30b 100755 --- a/libexec/pyenv-version-file +++ b/libexec/pyenv-version-file @@ -8,6 +8,9 @@ target_dir="$1" find_local_version_file() { local root="$1" + # Nonexistent paths are UB as of this writing. + # Relative ones cause a failure but absolute ones don't + [[ $root != /* ]] && root=$(CDPATH= cd -- "$root" && pwd) while ! [[ "$root" =~ ^//[^/]*$ ]]; do if [ -f "${root}/.python-version" ]; then echo "${root}/.python-version" diff --git a/test/version-file.bats b/test/version-file.bats index e2fb941c..3c0d40a2 100644 --- a/test/version-file.bats +++ b/test/version-file.bats @@ -73,3 +73,15 @@ create_file() { run pyenv-version-file "$PWD" assert_failure "" } + +@test "walks up beyond cwd for a relative path" { + create_file ".python-version" + mkdir -p project/subdir + cd project + # Run with CPU-time limit because this used to loop forever + run bash -c 'ulimit -t 5; pyenv-version-file .' + assert_success "${PYENV_TEST_DIR}/.python-version" + + run pyenv-version-file ./subdir + assert_success "${PYENV_TEST_DIR}/.python-version" +}