diff options
author | Zac Medico <zmedico@gentoo.org> | 2013-05-21 14:37:13 -0700 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2013-05-21 14:37:13 -0700 |
commit | 4c5b4a1df363a61ecb0590d64adc12e167903006 (patch) | |
tree | b4513dc0e22836e0b424f83072378babacdb8c65 | |
parent | *_DEFAULT_OPTS: shlex for embedded quotes (diff) | |
download | portage-4c5b4a1df363a61ecb0590d64adc12e167903006.tar.gz portage-4c5b4a1df363a61ecb0590d64adc12e167903006.tar.bz2 portage-4c5b4a1df363a61ecb0590d64adc12e167903006.zip |
ecompressdir: indirect symlinks, bug #470916
-rwxr-xr-x | bin/ebuild-helpers/ecompressdir | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/bin/ebuild-helpers/ecompressdir b/bin/ebuild-helpers/ecompressdir index 40079c0d8..eca588869 100755 --- a/bin/ebuild-helpers/ecompressdir +++ b/bin/ebuild-helpers/ecompressdir @@ -85,6 +85,11 @@ funk_up_dir() { find "${dir}" "${args[@]}" -print0 | ${XARGS} -0 ${binary} ((ret|=$?)) + # Repeat until nothing changes, in order to handle multiple + # levels of indirection (see bug #470916). + local -i indirection=0 + while true ; do + local something_changed= while read -r -d $'\0' brokenlink ; do [[ -e ${brokenlink} ]] && continue olddest=$(readlink "${brokenlink}") @@ -110,12 +115,22 @@ funk_up_dir() { else [[ -f "${dir}/${brokenlink%/*}/${newdest}" ]] || continue fi + something_changed=${brokenlink} rm -f "${brokenlink}" [[ ${act} == "compress" ]] \ && ln -snf "${newdest}" "${brokenlink}${suffix}" \ || ln -snf "${newdest}" "${brokenlink%${suffix}}" ((ret|=$?)) done < <(find "${dir}" -type l -print0) + [[ -n ${something_changed} ]] || break + (( indirection++ )) + if (( indirection >= 100 )) ; then + # Protect against possibility of a bug triggering an endless loop. + eerror "ecompressdir: too many levels of indirection for" \ + "'${actual_dir#${ED}}/${something_changed#./}'" + break + fi + done return ${ret} } |