From 47d99c206a6da346d35fa3634bf7a19ee7ec17aa Mon Sep 17 00:00:00 2001 From: Renaud Guillard Date: Wed, 13 Mar 2024 23:14:45 +0100 Subject: [PATCH] XSH library - Fix ns_relativepath edge case * Fix invalid path produced by ns_relativepath when the common parent of paths is "/" * Add ns_relativepath unit test * Update tools --- ns/sh/new-xsh.sh | 4 +- ns/sh/xsltdeps.sh | 4 +- ns/xsh/lib/filesystem/filesystem.xsh | 4 +- tests/xsh/relativepath.xsh | 78 ++++++++++++++++++++++++++++ tools/sh/run-tests.sh | 4 +- tools/sh/update-c-parser.sh | 4 +- tools/sh/update-doc.sh | 4 +- tools/sh/update-php-parser.sh | 4 +- tools/sh/update-python-parser.sh | 4 +- 9 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 tests/xsh/relativepath.xsh diff --git a/ns/sh/new-xsh.sh b/ns/sh/new-xsh.sh index 2111d0d..a5dc3aa 100755 --- a/ns/sh/new-xsh.sh +++ b/ns/sh/new-xsh.sh @@ -992,7 +992,9 @@ ns_relativepath() do res="${res}/.." done - res="${res}${from#${sub}}" + [ "${sub}" != '/' ] \ + && res="${res}${from#${sub}}" \ + || res="${res}${from}" res="${res#./}" [ -z "${res}" ] && res='.' echo "${res}" diff --git a/ns/sh/xsltdeps.sh b/ns/sh/xsltdeps.sh index f4988e3..6c7d0ef 100755 --- a/ns/sh/xsltdeps.sh +++ b/ns/sh/xsltdeps.sh @@ -700,7 +700,9 @@ ns_relativepath() do res="${res}/.." done - res="${res}${from#${sub}}" + [ "${sub}" != '/' ] \ + && res="${res}${from#${sub}}" \ + || res="${res}${from}" res="${res#./}" [ -z "${res}" ] && res='.' echo "${res}" diff --git a/ns/xsh/lib/filesystem/filesystem.xsh b/ns/xsh/lib/filesystem/filesystem.xsh index fcb98da..61f356e 100644 --- a/ns/xsh/lib/filesystem/filesystem.xsh +++ b/ns/xsh/lib/filesystem/filesystem.xsh @@ -68,7 +68,9 @@ for ((i=0;${i}<${c};i++)) do res="${res}/.." done -res="${res}${from#${sub}}" +[ "${sub}" != '/' ] \ + && res="${res}${from#${sub}}" \ + || res="${res}${from}" res="${res#./}" [ -z "${res}" ] && res='.' echo "${res}" diff --git a/tests/xsh/relativepath.xsh b/tests/xsh/relativepath.xsh new file mode 100644 index 0000000..c21cd79 --- /dev/null +++ b/tests/xsh/relativepath.xsh @@ -0,0 +1,78 @@ + + + + + + + + + $(ns_mktempdir "ns_testsuite_relativepath_root") + $(pwd) + + + + + + &2 + return 1 +fi + +for t in \ + 'foo:bar:../foo' \ + 'foo:foo:.' \ + 'foo:foo/bar:..' \ + 'foo/bar:huey/dewey/louie:../../../foo/bar' \ + '/bin/echo:/etc/hosts:../bin/echo' +do + target="$(cut -f 1 -d':' <<< "${t}")" + source="$(cut -f 2 -d':' <<< "${t}")" + expected="$(cut -f 3 -d':' <<< "${t}")" + + if [ "${target:0:1}" != '/' ] + then + mkdir -p "${ns_testsuite_relativepath_root}/${target}" \ + || return 1 + target="$(ns_realpath "${ns_testsuite_relativepath_root}/${target}")" + [ -d "${target}" ] || return 1 + elif [ ! -r "${target}" ] + then + echo 'warning: ' "${target} does not exists" 1>&2 + continue + fi + + if [ "${source:0:1}" != '/' ] + then + mkdir -p "${ns_testsuite_relativepath_root}/${source}" \ + || return 1 + source="$(ns_realpath "${ns_testsuite_relativepath_root}/${source}")" + [ -d "${source}" ] || return 1 + elif [ ! -r ${source} ] + then + echo 'warning: ' "${source} does not exists" 1>&2 + continue + fi + + actual="$(ns_relativepath "${target}" "${source}")" + if [ "${actual}" != "${expected}" ] + then + printf "%-10.10s: %s\n" Source "${source#${ns_testsuite_relativepath_root}/}" + printf "%-10.10s: %s\n" Target "${target#${ns_testsuite_relativepath_root}/}" + printf "%-10.10s: %s\n" "Expected" "${expected}" + printf "%-10.10s: %s\n" Actual "${actual}" + return 1 + fi + +done + +################################################### +return 0 +]]> + + diff --git a/tools/sh/run-tests.sh b/tools/sh/run-tests.sh index da5a8c6..e85af02 100755 --- a/tools/sh/run-tests.sh +++ b/tools/sh/run-tests.sh @@ -1245,7 +1245,9 @@ ns_relativepath() do res="${res}/.." done - res="${res}${from#${sub}}" + [ "${sub}" != '/' ] \ + && res="${res}${from#${sub}}" \ + || res="${res}${from}" res="${res#./}" [ -z "${res}" ] && res='.' echo "${res}" diff --git a/tools/sh/update-c-parser.sh b/tools/sh/update-c-parser.sh index be3fb77..0ecea74 100755 --- a/tools/sh/update-c-parser.sh +++ b/tools/sh/update-c-parser.sh @@ -555,7 +555,9 @@ ns_relativepath() do res="${res}/.." done - res="${res}${from#${sub}}" + [ "${sub}" != '/' ] \ + && res="${res}${from#${sub}}" \ + || res="${res}${from}" res="${res#./}" [ -z "${res}" ] && res='.' echo "${res}" diff --git a/tools/sh/update-doc.sh b/tools/sh/update-doc.sh index 8329edc..87af603 100755 --- a/tools/sh/update-doc.sh +++ b/tools/sh/update-doc.sh @@ -1103,7 +1103,9 @@ ns_relativepath() do res="${res}/.." done - res="${res}${from#${sub}}" + [ "${sub}" != '/' ] \ + && res="${res}${from#${sub}}" \ + || res="${res}${from}" res="${res#./}" [ -z "${res}" ] && res='.' echo "${res}" diff --git a/tools/sh/update-php-parser.sh b/tools/sh/update-php-parser.sh index 221e10c..dd66a37 100755 --- a/tools/sh/update-php-parser.sh +++ b/tools/sh/update-php-parser.sh @@ -553,7 +553,9 @@ ns_relativepath() do res="${res}/.." done - res="${res}${from#${sub}}" + [ "${sub}" != '/' ] \ + && res="${res}${from#${sub}}" \ + || res="${res}${from}" res="${res#./}" [ -z "${res}" ] && res='.' echo "${res}" diff --git a/tools/sh/update-python-parser.sh b/tools/sh/update-python-parser.sh index 13ca751..cc9330d 100755 --- a/tools/sh/update-python-parser.sh +++ b/tools/sh/update-python-parser.sh @@ -553,7 +553,9 @@ ns_relativepath() do res="${res}/.." done - res="${res}${from#${sub}}" + [ "${sub}" != '/' ] \ + && res="${res}${from#${sub}}" \ + || res="${res}${from}" res="${res#./}" [ -z "${res}" ] && res='.' echo "${res}"