From 1440f3cb8df523155a1d26f9bf20025b697e3faf Mon Sep 17 00:00:00 2001 From: Marcin Sulikowski Date: Fri, 8 Mar 2019 19:17:17 +0000 Subject: [PATCH] buildpackage-funcs: Fix whitespace handling in .dsc paths We've noticed that pbuilder fails to build source packages located in directories which contain spaces within their names. For example, the following: $ pbuilder build "/tmp/source packages/pbuilder_0.230.2.dsc" fails with an error like this: I: Building the build Environment I: extracting base tarball [/var/cache/pbuilder/base.tgz] I: copying local configuration I: mounting /proc filesystem I: mounting /sys filesystem I: creating /{dev,run}/shm I: mounting /dev/pts filesystem I: redirecting /dev/ptmx to /dev/pts/ptmx I: policy-rc.d already exists I: Obtaining the cached apt archive contents I: Copying source file awk: cmd. line:5: /^ / {if (p){print "/tmp/source awk: cmd. line:5: ^ unterminated string awk: cmd. line:5: /^ / {if (p){print "/tmp/source awk: cmd. line:5: ^ syntax error I: copying [/tmp/source] cp: cannot stat '/tmp/source': No such file or directory I: unmounting dev/ptmx filesystem I: unmounting dev/pts filesystem (...) Those problems are caused by the fact that: * The `get822files` function incorrectly concatenates strings in: awk '(...) {print "'$(dirname "$input")'/" $'${field}'}' When `$(dirname "$input")` contains whitespace, the awk script is divided by `bash` into multiple arguments for `awk` which causes the errors mentioned in the output above. * The `get822files` function is designed to return a list of paths separated by a single space character, which makes it impossible to parse its output when it looks like this: source packages/pbuilder_0.230.2.dsc source packages/pbuilder_0.230.2.tar.xz These issues make it impossible for pbuilder to copy the given source package to its chroot environment even though the rest of pbuilder's code is designed to handle whitespace in file names. We fix this by changing how the `get822files` function is supposed to work -- instead of listing paths separated by a single space, it now lists paths separated by LF characters which, although still allowed in paths, are almost never used in directory names. As a by-product, path of the source package may now contain any characters except for LF, including `'` and `"` which were not handled correctly before this fix as well. Signed-off-by: Marcin Sulikowski --- pbuilder-buildpackage | 4 ++-- pbuilder-buildpackage-funcs | 27 +++++++++++----------- "t/data/fool's \"data /dsc" | 37 ++++++++++++++++++++++++++++++ t/test_pbuilder-buildpackage-funcs | 23 ++++++++++++++++--- 4 files changed, 72 insertions(+), 19 deletions(-) create mode 100644 "t/data/fool's \"data /dsc" diff --git a/pbuilder-buildpackage b/pbuilder-buildpackage index d43cec1d..e597ee42 100755 --- a/pbuilder-buildpackage +++ b/pbuilder-buildpackage @@ -289,11 +289,11 @@ if [ -d "${BUILDRESULT}" ]; then else FILES=$(get822files "changes" "$ARCH_CHANGES_FILE") fi - for FILE in $FILES; do + while read -r FILE; do if [ -f "${FILE}" ]; then cp -p "${FILE}" "${BUILDRESULT}" || true fi - done + done <<< "${FILES}" export_additional_buildresults executehooks "I" else diff --git a/pbuilder-buildpackage-funcs b/pbuilder-buildpackage-funcs index a1a801b2..a98c4d73 100644 --- a/pbuilder-buildpackage-funcs +++ b/pbuilder-buildpackage-funcs @@ -24,34 +24,33 @@ get822files () { # get list of files listed in the Files field of a .changes or .dsc (to - # be specified in the first parameter) + # be specified in the first parameter) and output them one file per line local type="$1" local input="$2" - local files=("$2") case $type in changes) local field=5 ;; dsc) local field=3 ;; *) log.error "unexpected error in get822files()" ; exit 1 ;; esac - files+=("$(cat "$input" | - awk 'BEGIN{p=0} - ! /^[ \t]/ {p=0} - /^Files:/ {p=1} - ! /^[ \t]*/ {p=0} - /^ / {if (p){print "'$(dirname "$input")'/" $'${field}'}}' | - tr '\n' ' ' | sed -e 's/[[:space:]]*$//')") - # ↑↑↑ because we are really picky (and we have picky tests...) - echo "${files[@]}" + echo "$input" + cat "$input" | awk -v dir="$(dirname "$input")" ' + BEGIN {p=0} + ! /^[ \t]/ {p=0} + /^[ \t]*$/ {p=0} + /^Files:/ {p=1} + /^ / && p {print dir "/" $'${field}'} + ' } function copydsc () { local DSCFILE=$(get822files "dsc" "$1") local TARGET="$2" - for FILE in ${DSCFILE[@]} ; do - log.i "copying [$FILE]" + local FILE + while read -r FILE ; do + log.i "copying [$FILE]" cp -p "$FILE" "$TARGET" chmod u+rw "$TARGET/$(basename "$FILE")" - done + done <<< "$DSCFILE" } function dsc_get_basename() { diff --git "a/t/data/fool's \"data /dsc" "b/t/data/fool's \"data /dsc" new file mode 100644 index 00000000..8fc9f998 --- /dev/null +++ "b/t/data/fool's \"data /dsc" @@ -0,0 +1,37 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +Format: 3.0 (quilt) +Source: haskell-concrete-typerep +Binary: libghc-concrete-typerep-dev, libghc-concrete-typerep-prof, libghc-concrete-typerep-doc +Architecture: any all +Version: 0.1.0.2-2 +Maintainer: Debian Haskell Group +Uploaders: Masayuki Hatta (mhatta) +Homepage: http://hackage.haskell.org/package/concrete-typerep +Standards-Version: 3.9.3 +Vcs-Browser: http://darcs.debian.org/cgi-bin/darcsweb.cgi?r=pkg-haskell/haskell-concrete-typerep +Vcs-Darcs: http://darcs.debian.org/darcs/pkg-haskell/haskell-concrete-typerep +Build-Depends: debhelper (>= 9), haskell-devscripts (>= 0.8.15), cdbs, ghc, ghc-prof, libghc-hashable-dev (<< 1.3), libghc-hashable-prof (<< 1.3) +Build-Depends-Indep: ghc-doc, libghc-hashable-doc (<< 1.3) +Package-List: + libghc-concrete-typerep-dev deb haskell extra + libghc-concrete-typerep-doc deb doc extra + libghc-concrete-typerep-prof deb haskell extra +Checksums-Sha1: + 7dc356eef28c83f606b792e3d39b68a04c1a6d98 3159 haskell-concrete-typerep_0.1.0.2.orig.tar.gz + 10710e36d3e55272169c8600f1dd558fe2102217 2232 haskell-concrete-typerep_0.1.0.2-2.debian.tar.gz +Checksums-Sha256: + f72a41d9d8315528c7b0e13bf61e6122c7d236cb529c207cfb431cf272439e1f 3159 haskell-concrete-typerep_0.1.0.2.orig.tar.gz + 34f25f113fd7762ffc783cb9f2942e78bd10546826c76e76ad30d89a9ede9471 2232 haskell-concrete-typerep_0.1.0.2-2.debian.tar.gz +Files: + 5638a296661fb65145dfbc062cfa53db 3159 haskell-concrete-typerep_0.1.0.2.orig.tar.gz + cb67a46d6b00af4fc5769c11ae6c99f8 2232 haskell-concrete-typerep_0.1.0.2-2.debian.tar.gz + +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.12 (GNU/Linux) + +iEYEARECAAYFAlGgkLEACgkQ9ijrk0dDIGyOhgCfd5PqA5Uy3l26+sfU0PfnxRX5 +Do4AnRDBnUTngXlbdIx1NpsgUsLluc1U +=qQyP +-----END PGP SIGNATURE----- diff --git a/t/test_pbuilder-buildpackage-funcs b/t/test_pbuilder-buildpackage-funcs index f1d16ab9..1207717e 100755 --- a/t/test_pbuilder-buildpackage-funcs +++ b/t/test_pbuilder-buildpackage-funcs @@ -54,6 +54,10 @@ test_getchangesfilesNormal () { get822files changes "$DEBIAN_CONTROL" } +test_getdscfilesWithInsaneParentDir () { + get822files dsc "$TESTDATA_DIR/fool's \"data /dsc" +} + test_dsc_get_basename_normal_with_revision() { dsc_get_basename "$TESTDATA_DIR/dsc1" yes } @@ -120,9 +124,22 @@ BUILDPLACE="$TEMP_DIR" BUILDDIR='' BUILDSUBDIR=fake-pkg -expect_output "$DEBIAN_CONTROL $TEMP_DIR/haskell-concrete-typerep_0.1.0.2.orig.tar.gz $TEMP_DIR/haskell-concrete-typerep_0.1.0.2-2.debian.tar.gz" test_getdscfilesNormal -expect_output "$DEBIAN_CONTROL $TEMP_DIR/golang-xmpp-dev_0.0~git20140304.orig.tar.gz $TEMP_DIR/golang-xmpp-dev_0.0~git20140304-1.debian.tar.xz" test_getdscfilesWithoutNL -expect_output "$DEBIAN_CONTROL $TEMP_DIR/pbuilder_0.225.2~bpo8+1.dsc $TEMP_DIR/pbuilder_0.225.2~bpo8+1.tar.xz $TEMP_DIR/pbuilder_0.225.2~bpo8+1_all.deb" test_getchangesfilesNormal +expect_output "$DEBIAN_CONTROL +$TEMP_DIR/haskell-concrete-typerep_0.1.0.2.orig.tar.gz +$TEMP_DIR/haskell-concrete-typerep_0.1.0.2-2.debian.tar.gz" test_getdscfilesNormal + +expect_output "$DEBIAN_CONTROL +$TEMP_DIR/golang-xmpp-dev_0.0~git20140304.orig.tar.gz +$TEMP_DIR/golang-xmpp-dev_0.0~git20140304-1.debian.tar.xz" test_getdscfilesWithoutNL + +expect_output "$DEBIAN_CONTROL +$TEMP_DIR/pbuilder_0.225.2~bpo8+1.dsc +$TEMP_DIR/pbuilder_0.225.2~bpo8+1.tar.xz +$TEMP_DIR/pbuilder_0.225.2~bpo8+1_all.deb" test_getchangesfilesNormal + +expect_output "$TESTDATA_DIR/fool's \"data /dsc +$TESTDATA_DIR/fool's \"data /haskell-concrete-typerep_0.1.0.2.orig.tar.gz +$TESTDATA_DIR/fool's \"data /haskell-concrete-typerep_0.1.0.2-2.debian.tar.gz" test_getdscfilesWithInsaneParentDir expect_output "haskell-concrete-typerep_0.1.0.2-2" test_dsc_get_basename_normal_with_revision expect_output "haskell-concrete-typerep_0.1.0.2" test_dsc_get_basename_normal_without_revision -- GitLab