commit:     bf17d5963cead8c930d3e996f976e57b99d839f8
Author:     Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Fri Jun  6 21:02:58 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Fri Jun  6 22:02:17 2025 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=bf17d596

bashrc-functions.sh: have register_{die,success}_hook() validate their 
parameters

Presently, the register_die_hook() and register_success_hook() functions
make use of the contains_word() function in order to determine whether
the 'EBUILD_DEATH_HOOKS' and 'EBUILD_SUCCESS_HOOKS' variables need to be
extended. This is so as to ensure that the same hook cannot be added
more than once.

  # Adds a hook for the my_cleanup function.
  register_die_hook my_cleanup

  # This is a no-op because the hook is already registered.
  register_die_hook my_cleanup

However, the contains_word() function will always return false where its
first argument contains whitespace, for which there is a good reason.

  # We may consider this to be a scalar variable comprising four words.
  wordlist='foo bar baz quux'

  # Thus, it would not be appropriate for this to return true.
  contains_word 'bar baz' "${wordlist}"

So far, so good. However, one must then consider that, whenever
contains_word() returns false, it is effectively granting permission for
the hook to be added again, giving rise to the following edge case.

  # Two hooks will be registered by the names of "bar" and "baz".
  # Not an intended use case; two arguments should be given.
  register_die_hook 'bar baz'

  # This will register both again, despite having been added already.
  register_die_hook 'bar baz'

To remedy this, have the register_die_hook() and register_success_hook()
functions validate their parameters. The nature of the validation is
straightforward: if a given parameter be empty, or contain any
whitespace, then it shall be considered as invalid and disregarded.

Though such cases should be vanishingly rare in practice, I would have
liked to raise a warning for them. However, /etc/portage/bashrc is
sourced so often that, barring an improved warning mechanism, it is
currently impractical.

Fixes: 3b0150e488972b02c45c71192507300d823a361f
See-also: 4a4631eef7186c29668a8c049d988b61469940fd
Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 bin/bashrc-functions.sh | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/bin/bashrc-functions.sh b/bin/bashrc-functions.sh
index 9b8b74dc7e..568f16da6c 100644
--- a/bin/bashrc-functions.sh
+++ b/bin/bashrc-functions.sh
@@ -6,7 +6,9 @@ register_die_hook() {
        local hook
 
        for hook; do
-               if ! contains_word "${hook}" "${EBUILD_DEATH_HOOKS}"; then
+               if [[ ${hook} != +([![:space:]]) ]]; then
+                       :
+               elif ! contains_word "${hook}" "${EBUILD_DEATH_HOOKS}"; then
                        export EBUILD_DEATH_HOOKS+=" ${hook}"
                fi
        done
@@ -16,7 +18,9 @@ register_success_hook() {
        local hook
 
        for hook; do
-               if ! contains_word "${hook}" "${EBUILD_SUCCESS_HOOKS}"; then
+               if [[ ${hook} != +([![:space:]]) ]]; then
+                       :
+               elif ! contains_word "${hook}" "${EBUILD_SUCCESS_HOOKS}"; then
                        export EBUILD_SUCCESS_HOOKS+=" ${hook}"
                fi
        done

Reply via email to