From f4b847e2008455c498409b38a77d346b6c87b1eb Mon Sep 17 00:00:00 2001 From: Andrew Robbins Date: Thu, 22 Jun 2017 07:00:15 -0400 Subject: Improved handling of filenames in archive creation Filenames listed in DOTTARFILES are now NUL terminated so that any with strange characters, such as a newline, do not negatively affect archive creation. DOTRNDSEED file which stores the random seed to be used by GCC during compilation is now included in the list of files to be archived. Cleaned up functions related to archive creation. --- libs/common | 184 +++++++++++++++++++++++++++++++----------------------------- libs/git | 6 +- 2 files changed, 97 insertions(+), 93 deletions(-) diff --git a/libs/common b/libs/common index 281728bc..513d697c 100755 --- a/libs/common +++ b/libs/common @@ -181,145 +181,149 @@ directory_filled_check() { } archive_files_create() { - local source_path=$1 - - local directory=$( basename "$source_path" ) - local tarfiles_path="$source_path/$DOTTARFILES" - local revision_path="$source_path/$DOTREVISION" - local version_path="$source_path/$DOTVERSION" - - if git_check "$source_path" - then - git_files "$source_path" | tr -d '\0' > "$tarfiles_path" - echo "$DOTTARFILES" | tr -d '\0' >> "$tarfiles_path" + local source_path="$1" + + local directory="$(basename "${source_path}")" + local tarfiles_path="${source_path}/${DOTTARFILES}" + local revision_path="${source_path}/${DOTREVISION}" + local version_path="${source_path}/${DOTVERSION}" + local epoch_path="${source_path}/${DOTEPOCH}" + local rnd_seed_path="${source_path}/${DOTRNDSEED}" + + # Files in "${tarfiles_path}" are NUL terminated. + # `tr '\0' '\n'` for human-readable output. + if git_check "${source_path}"; then + git_files "${source_path}" > "${tarfiles_path}" + printf '%s\0' "${DOTTARFILES}" >> "${tarfiles_path}" else - touch "$tarfiles_path" - - ( - cd "$source_path" - find - ) | LC_ALL=C sort | sed "s,^./,," | grep -vP "^\.$" > "$tarfiles_path" - fi - - if [ -f "$revision_path" ] - then - echo "$DOTREVISION" | tr -d '\0' >> "$tarfiles_path" - fi - - if [ -f "$version_path" ] - then - echo "$DOTVERSION" | tr -d '\0' >> "$tarfiles_path" + find "${source_path}" -print0 | env LC_ALL='C.UTF-8' sort -z | sed -z "1d;s,^${source_path}/\\?,,;/^${DOTTARFILES}\$/d" > "${tarfiles_path}" fi - if [ -f "$epoch_path" ] - then - echo "$DOTEPOCH" | tr -d '\0' >> "$tarfiles_path" - fi + for dotfile in "${revision_path}" \ + "${version_path}" \ + "${epoch_path}" \ + "${rnd_seed_path}" + do + if [[ -f "${dotfile}" ]]; then + printf '%s\0' ".${dotfile##*.}" >> "${tarfiles_path}" + fi + done } archive_files_date() { - local source_path=$1 + local source_path="$1" - local epoch_path="$source_path/$DOTEPOCH" + local epoch_path="${source_path}/${DOTEPOCH}" - if ! [ -z "$SOURCE_DATE_EPOCH" ] - then - ( - cd "$source_path" - find -exec touch --no-dereference --date="@$SOURCE_DATE_EPOCH" {} \; - ) + if [[ -n "${SOURCE_DATE_EPOCH}" ]]; then + find "${source_path}" -execdir touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" {} + fi } archive_create() { - local archive_path=$1 - local source_path=$2 - local directory=$3 + local archive_path="$1" + local source_path="$2" + local directory="$3" - local tarfiles_path="$source_path/$DOTTARFILES" - local directory_path=$( dirname "$archive_path" ) + local tarfiles_path="${source_path}/${DOTTARFILES}" + local directory_path="$(dirname "${archive_path}")" - mkdir -p "$directory_path" + mkdir -p "${directory_path}" - if [ -z "$directory" ] - then - directory=$( basename "$source_path" ) + if [[ -z "${directory}" ]]; then + directory="$(basename "${source_path}")" fi - archive_files_create "$source_path" - archive_files_date "$source_path" + archive_files_create "${source_path}" + archive_files_date "${source_path}" + + local tar_options=( + --create + --xz + --file="${archive_path}" + --files-from="${tarfiles_path}" + --transform="s,^,${directory}/,S" + --no-recursion + --null + --owner=0 + --group=0 + --numeric-owner + ) ( - cd "$source_path" - tar -cJf "$archive_path" --no-recursion -T "$tarfiles_path" --transform="s,^,$directory/,S" --owner=root --group=root --numeric-owner + cd "${source_path}" + tar "${tar_options[@]}" ) } archive_extract() { - local archive_path=$1 - local destination_path=$2 + local archive_path="$1" + local destination_path="$2" - if [ -z "$destination_path" ] - then - destination_path=$( dirname "$archive_path" ) + if [[ -z "${destination_path}" ]]; then + destination_path="$(dirname "${archive_path}")" fi - tar -xf "$archive_path" -ps -C "$destination_path" + tar -xf "${archive_path}" -ps -C "${destination_path}" } rootfs_files_create() { - local source_path=$1 - - local directory=$( basename "$source_path" ) - local tarfiles_path="$source_path/$DOTTARFILES" + local source_path="$1" - touch "$tarfiles_path" + local directory="$(basename "${source_path}")" + local tarfiles_path="${source_path}/${DOTTARFILES}" - ( - cd "$source_path" - execute_root find - ) | LC_ALL=C sort | sed "s,^./,," | grep -vP "^$DOTTARFILES|^\.$" > "$tarfiles_path" + # Files in "${tarfiles_path}" are NUL terminated. + # `tr '\0' '\n'` for human-readable output. + execute_root find "${source_path}" -print0 | env LC_ALL='C.UTF-8' sort -z | sed -z "1d;s,^${source_path}/\\?,,;/^${DOTTARFILES}\$/d" > "${tarfiles_path}" } rootfs_files_date() { - local source_path=$1 + local source_path="$1" - local epoch_path="$source_path/$DOTEPOCH" + local epoch_path="${source_path}/${DOTEPOCH}" - if ! [ -z "$SOURCE_DATE_EPOCH" ] - then - ( - cd "$source_path" - execute_root find -exec touch --no-dereference --date="@$SOURCE_DATE_EPOCH" {} \; - ) + if [[ -n "${SOURCE_DATE_EPOCH}" ]]; then + execute_root find "${source_path}" -execdir touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" {} + fi } rootfs_create() { - local rootfs_path=$1 - local source_path=$2 - local directory=$3 + local rootfs_path="$1" + local source_path="$2" + local directory="$3" - local tarfiles_path="$source_path/$DOTTARFILES" - local directory_path=$( dirname "$rootfs_path" ) + local tarfiles_path="${source_path}/${DOTTARFILES}" + local directory_path="$(dirname "${rootfs_path}")" - mkdir -p "$directory_path" + mkdir -p "${directory_path}" - if [ -z "$directory" ] - then - directory=$( basename "$source_path" ) + if [[ -z "${directory}" ]]; then + directory="$(basename "${source_path}")" fi - rootfs_files_create "$source_path" - rootfs_files_date "$source_path" + rootfs_files_create "${source_path}" + rootfs_files_date "${source_path}" + + local tar_options=( + --create + --xz + --file="${rootfs_path}" + --files-from="${tarfiles_path}" + --no-recursion + --null + --owner=0 + --group=0 + --numeric-owner + ) ( - cd "$source_path" - execute_root tar -cJf "$rootfs_path" --no-recursion -T "$tarfiles_path" --numeric-owner + cd "${source_path}" + execute_root tar "${tar_options[@]}" ) - execute_root chmod 644 "$rootfs_path" - execute_root chown $USER:$USER "$rootfs_path" + execute_root chmod 644 "${rootfs_path}" + execute_root chown "${USER}:${USER}" "${rootfs_path}" } requirements() { diff --git a/libs/git b/libs/git index a750be32..97352956 100755 --- a/libs/git +++ b/libs/git @@ -202,12 +202,12 @@ git_describe() { } git_files() { - local repository_path=$1 + local repository_path="$1" ( - cd "$repository_path" + cd "${repository_path}" # Reproducible sorting. - git ls-files | LC_ALL=C sort -z + git ls-files -z | env LC_ALL='C.UTF-8' sort -z ) } -- cgit v1.2.3-70-g09d2