From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id E080D15812E for ; Fri, 9 Jun 2023 11:02:29 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 133D8E07F6; Fri, 9 Jun 2023 11:02:29 +0000 (UTC) Received: from smtp.gentoo.org (dev.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 8A3ACE07F6 for ; Fri, 9 Jun 2023 11:02:28 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id BCAEC340D40 for ; Fri, 9 Jun 2023 11:02:27 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 3313DA8D for ; Fri, 9 Jun 2023 11:02:26 +0000 (UTC) From: "Sam James" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Sam James" Message-ID: <1686293830.2a78a15de6e5d90da0657bf74929993b1b51a337.sam@gentoo> Subject: [gentoo-commits] proj/gentoo-functions:master commit in: / X-VCS-Repository: proj/gentoo-functions X-VCS-Files: functions.sh test-functions X-VCS-Directories: / X-VCS-Committer: sam X-VCS-Committer-Name: Sam James X-VCS-Revision: 2a78a15de6e5d90da0657bf74929993b1b51a337 X-VCS-Branch: master Date: Fri, 9 Jun 2023 11:02:26 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 8ce94ec8-f458-4c97-be42-0855137d0306 X-Archives-Hash: a763453017daa17b9425a133635a0b5a commit: 2a78a15de6e5d90da0657bf74929993b1b51a337 Author: Kerin Millar plushkava net> AuthorDate: Thu Jun 8 05:48:02 2023 +0000 Commit: Sam James gentoo org> CommitDate: Fri Jun 9 06:57:10 2023 +0000 URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=2a78a15d Add a chdir() function to act as a safer alternative to the cd builtin To run cd "$dir" is problematic because: 1) it may consider its operand as an option 2) it will search CDPATH for an operand not beginning with ./, ../ or / 3) it will switch to OLDPWD if the operand is - 4) cdable_vars causes bash to treat the operand as a potential varname This commit introduces a chdir() function that addresses all of these pitfalls. Signed-off-by: Kerin Millar plushkava.net> Signed-off-by: Sam James gentoo.org> functions.sh | 18 +++++++++++++++++ test-functions | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/functions.sh b/functions.sh index 7838c90..154c8a4 100644 --- a/functions.sh +++ b/functions.sh @@ -534,6 +534,24 @@ is_int() { esac } +# +# A safe wrapper for the cd builtin. To run cd "$dir" is problematic because: +# +# 1) it may consider its operand as an option +# 2) it will search CDPATH for an operand not beginning with ./, ../ or / +# 3) it will switch to OLDPWD if the operand is - +# 4) cdable_vars causes bash to treat the operand as a potential variable name +# +chdir() { + if [ "$BASH" ]; then + shopt -u cdable_vars + fi + if [ "$1" = - ]; then + set -- ./- + fi + CDPATH= cd -- "$@" +} + # # Determine whether the first operand contains any visible characters. # diff --git a/test-functions b/test-functions index b80587b..5a6b23b 100755 --- a/test-functions +++ b/test-functions @@ -14,7 +14,7 @@ bailout() { assign_tmpdir() { # shellcheck disable=1007 dir=$(mktemp -d) \ - && CDPATH= cd -- "${dir}" \ + && chdir "${dir}" \ || bailout "Couldn't create or change to the temp dir" } @@ -24,6 +24,49 @@ cleanup_tmpdir() { fi } +test_chdir() { + set -- \ + 1 grandchild \ + 1 var \ + 0 -L \ + 0 -p \ + 0 -e \ + 0 -@ \ + 0 - \ + 0 child + + if ! mkdir -p -- -L -p -e -@ - child child/grandchild; then + bailout "Couldn't set up all test directories" + fi + + callback() { + shift + test_description="chdir $(print_args "$@")" + if [ "$BASH" ]; then + shopt -s cdable_vars + fi + CDPATH=child var=$CDPATH chdir "$@" \ + && test "$PWD" != "$OLDPWD" \ + && cd - >/dev/null + } + + iterate_tests 2 "$@" +} + +test_chdir_noop() { + set -- 0 '' + + callback() { + shift + test_description="chdir $(print_args "$@")" + chdir "$@" \ + && test "$PWD" = "$OLDPWD" \ + || { cd - >/dev/null; false; } + } + + iterate_tests 2 "$@" +} + test_is_older_than() { set -- \ 1 N/A N/A \ @@ -317,12 +360,24 @@ iterate_tests() { fi done eval "${code}" - if [ "$?" -eq "$1" ]; then + case $? in + 0) + test "$?" -eq "$1" + ;; + *) + test "$?" -ge "$1" + esac + if [ "$?" -eq 0 ]; then passed=$((passed + 1)) else printf 'not ' fi - printf 'ok %d - %s (expecting %d)\n' "${i}" "${test_description}" "$1" + if [ "$1" -eq 0 ]; then + expected=$1 + else + expected=">=$1" + fi + printf 'ok %d - %s (expecting %s)\n' "${i}" "${test_description}" "${expected}" shift "${slice_width}" done return "$(( passed < total ))" @@ -359,6 +414,8 @@ export TEST_GENFUNCS=1 export TZ=UTC rc=0 +test_chdir || rc=1 +test_chdir_noop || rc=1 ( ewarn() { true; }; test_is_older_than ) || rc=1 test_get_bootparam || rc=1 test_esyslog || rc=1