libmakepkg/lint_pkgbuild: lint depends/etc. as if they are pkgname

depends, provides, conflicts, replaces, and other variables that are
meant to contain package names, are now checked to ensure

1) the name component contains only characters that would equate to
   a valid pkgname.
2) the version component contains only characters that would equate
   to a valid pkgver.
3) comparison operator is a valid comparison operator (e.g. provides
   only allows exact = while optdepends doesn't allow anything)

This also refactors pkgname into a shared utility function, wires up
pkgbase optdepends and provides to use it, and gives pkgver a touchup
to allow referencing where it was called from.

Fixes FS#57833 and a bit of extra.

Signed-off-by: Eli Schwartz <eschwartz@archlinux.org>
Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
Eli Schwartz 2018-04-03 17:48:14 -04:00 committed by Allan McRae
parent bcaf1b84ff
commit 91b72cc386
11 changed files with 312 additions and 82 deletions

View file

@ -69,8 +69,12 @@ LIBMAKEPKG_IN = \
libmakepkg/lint_pkgbuild/arch.sh \
libmakepkg/lint_pkgbuild/backup.sh \
libmakepkg/lint_pkgbuild/changelog.sh \
libmakepkg/lint_pkgbuild/checkdepends.sh \
libmakepkg/lint_pkgbuild/conflicts.sh \
libmakepkg/lint_pkgbuild/depends.sh \
libmakepkg/lint_pkgbuild/epoch.sh \
libmakepkg/lint_pkgbuild/install.sh \
libmakepkg/lint_pkgbuild/makedepends.sh \
libmakepkg/lint_pkgbuild/optdepends.sh \
libmakepkg/lint_pkgbuild/options.sh \
libmakepkg/lint_pkgbuild/package_function.sh \

View file

@ -0,0 +1,56 @@
#!/bin/bash
#
# checkdepends.sh - Check the 'checkdepends' array conforms to requirements.
#
# Copyright (c) 2014-2018 Pacman Development Team <pacman-dev@archlinux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_CHECKDEPENDS_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_CHECKDEPENDS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/pkgname.sh"
source "$LIBRARY/lint_pkgbuild/pkgver.sh"
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_checkdepends')
lint_checkdepends() {
local checkdepends_list checkdepend name ver ret=0
get_pkgbuild_all_split_attributes checkdepends checkdepends_list
# save our shell options and turn on extglob
local shellopts=$(shopt -p)
shopt -s extglob
for checkdepend in "${checkdepends_list[@]}"; do
name=${checkdepend%%@(<|>|=|>=|<=)*}
ver=${checkdepend#*@(<|>|=|>=|<=)}
lint_one_pkgname checkdepends "$name" || ret=1
if [[ $ver != $checkdepend ]]; then
check_pkgver "$ver" checkdepends || ret=1
fi
done
eval "$shellopts"
return $ret
}

View file

@ -0,0 +1,56 @@
#!/bin/bash
#
# conflicts.sh - Check the 'conflicts' array conforms to requirements.
#
# Copyright (c) 2014-2018 Pacman Development Team <pacman-dev@archlinux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_CONFLICTS_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_CONFLICTS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/pkgname.sh"
source "$LIBRARY/lint_pkgbuild/pkgver.sh"
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_conflicts')
lint_conflicts() {
local conflicts_list conflict name ver ret=0
get_pkgbuild_all_split_attributes conflicts conflicts_list
# save our shell options and turn on extglob
local shellopts=$(shopt -p)
shopt -s extglob
for conflict in "${conflicts_list[@]}"; do
name=${conflict%%@(<|>|=|>=|<=)*}
ver=${conflict#*@(<|>|=|>=|<=)}
lint_one_pkgname conflicts "$name" || ret=1
if [[ $ver != $conflict ]]; then
check_pkgver "$ver" conflicts || ret=1
fi
done
eval "$shellopts"
return $ret
}

View file

@ -0,0 +1,56 @@
#!/bin/bash
#
# depends.sh - Check the 'depends' array conforms to requirements.
#
# Copyright (c) 2014-2018 Pacman Development Team <pacman-dev@archlinux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_DEPENDS_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_DEPENDS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/pkgname.sh"
source "$LIBRARY/lint_pkgbuild/pkgver.sh"
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_depends')
lint_depends() {
local depends_list depend name ver ret=0
get_pkgbuild_all_split_attributes depends depends_list
# save our shell options and turn on extglob
local shellopts=$(shopt -p)
shopt -s extglob
for depend in "${depends_list[@]}"; do
name=${depend%%@(<|>|=|>=|<=)*}
ver=${depend#*@(<|>|=|>=|<=)}
lint_one_pkgname depends "$name" || ret=1
if [[ $ver != $depend ]]; then
check_pkgver "$ver" depends || ret=1
fi
done
eval "$shellopts"
return $ret
}

View file

@ -0,0 +1,56 @@
#!/bin/bash
#
# makedepends.sh - Check the 'makedepends' array conforms to requirements.
#
# Copyright (c) 2014-2018 Pacman Development Team <pacman-dev@archlinux.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
[[ -n "$LIBMAKEPKG_LINT_PKGBUILD_MAKEDEPENDS_SH" ]] && return
LIBMAKEPKG_LINT_PKGBUILD_MAKEDEPENDS_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/pkgname.sh"
source "$LIBRARY/lint_pkgbuild/pkgver.sh"
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
lint_pkgbuild_functions+=('lint_makedepends')
lint_makedepends() {
local makedepends_list makedepend name ver ret=0
get_pkgbuild_all_split_attributes makedepends makedepends_list
# save our shell options and turn on extglob
local shellopts=$(shopt -p)
shopt -s extglob
for makedepend in "${makedepends_list[@]}"; do
name=${makedepend%%@(<|>|=|>=|<=)*}
ver=${makedepend#*@(<|>|=|>=|<=)}
lint_one_pkgname makedepends "$name" || ret=1
if [[ $ver != $makedepend ]]; then
check_pkgver "$ver" makedepends || ret=1
fi
done
eval "$shellopts"
return $ret
}

View file

@ -33,31 +33,13 @@ lint_pkgbuild_functions+=('lint_optdepends')
lint_optdepends() {
local a list name optdepends_list ret=0
optdepends_list=("${optdepends[@]}")
for a in "${arch[@]}"; do
array_build list "optdepends_$a"
optdepends_list+=("${list[@]}")
done
local optdepends_list optdepend name ret=0
for name in "${pkgname[@]}"; do
if extract_function_variable "package_$name" optdepends 1 list; then
optdepends_list+=("${list[@]}")
fi
get_pkgbuild_all_split_attributes optdepends optdepends_list
for a in "${arch[@]}"; do
if extract_function_variable "package_$name" "optdepends_$a" 1 list; then
optdepends_list+=("${list[@]}")
fi
done
done
for name in "${optdepends_list[@]}"; do
local pkg=${name%%:[[:space:]]*}
# the '-' character _must_ be first or last in the character range
if [[ $pkg != +([-[:alnum:]><=.+_:]) ]]; then
error "$(gettext "Invalid syntax for %s: '%s'")" "optdepend" "$name"
ret=1
fi
for optdepend in "${optdepends_list[@]}"; do
name=${optdepend%%:[[:space:]]*}
lint_one_pkgname optdepends "$name" || ret=1
done
return $ret

View file

@ -23,6 +23,7 @@ LIBMAKEPKG_LINT_PKGBUILD_PKGBASE_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/pkgname.sh"
source "$LIBRARY/util/message.sh"
@ -30,21 +31,9 @@ lint_pkgbuild_functions+=('lint_pkgbase')
lint_pkgbase() {
local ret=0
if [[ ${pkgbase:0:1} = "-" ]]; then
error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
return 1
fi
if [[ ${pkgbase:0:1} = "." ]]; then
error "$(gettext "%s is not allowed to start with a dot.")" "pkgbase"
ret=1
fi
if [[ $pkgbase = *[^[:alnum:]+_.@-]* ]]; then
error "$(gettext "%s contains invalid characters: '%s'")" \
'pkgbase' "${i//[[:alnum:]+_.@-]}"
ret=1
if [[ -z $pkgbase ]]; then
return 0
fi
return $ret
lint_one_pkgname "pkgbase" "$pkgbase"
}

View file

@ -29,34 +29,43 @@ source "$LIBRARY/util/message.sh"
lint_pkgbuild_functions+=('lint_pkgname')
lint_one_pkgname() {
local type=$1 name=$2 ret=0
if [[ -z $name ]]; then
error "$(gettext "%s is not allowed to be empty.")" "$type"
ret=1
continue
fi
if [[ ${name:0:1} = "-" ]]; then
error "$(gettext "%s is not allowed to start with a hyphen.")" "$type"
ret=1
fi
if [[ ${name:0:1} = "." ]]; then
error "$(gettext "%s is not allowed to start with a dot.")" "$type"
ret=1
fi
if [[ $name = *[^[:alnum:]+_.@-]* ]]; then
error "$(gettext "%s contains invalid characters: '%s'")" \
"$type" "${name//[[:alnum:]+_.@-]}"
ret=1
fi
return $ret
}
lint_pkgname() {
local ret=0 i
if [[ -z ${pkgname[@]} ]]; then
error "$(gettext "%s is not allowed to be empty.")" "pkgname"
return 1
fi
ret=1
else
for i in "${pkgname[@]}"; do
if [[ -z $i ]]; then
error "$(gettext "%s is not allowed to be empty.")" "pkgname"
ret=1
continue
fi
if [[ ${i:0:1} = "-" ]]; then
error "$(gettext "%s is not allowed to start with a hyphen.")" "pkgname"
ret=1
fi
if [[ ${i:0:1} = "." ]]; then
error "$(gettext "%s is not allowed to start with a dot.")" "pkgname"
ret=1
fi
if [[ $i = *[^[:alnum:]+_.@-]* ]]; then
error "$(gettext "%s contains invalid characters: '%s'")" \
'pkgname' "${i//[[:alnum:]+_.@-]}"
ret=1
fi
lint_one_pkgname "pkgname" "$i" || ret=1
done
fi
return $ret
}

View file

@ -30,13 +30,15 @@ lint_pkgbuild_functions+=('lint_pkgver')
check_pkgver() {
if [[ -z $1 ]]; then
error "$(gettext "%s is not allowed to be empty.")" "pkgver"
local ver=$1 type=$2
if [[ -z $ver ]]; then
error "$(gettext "%s is not allowed to be empty.")" "pkgver${type:+ in $type}"
return 1
fi
if [[ $1 = *[[:space:]/:-]* ]]; then
error "$(gettext "%s is not allowed to contain colons, forward slashes, hyphens or whitespace.")" "pkgver"
if [[ $ver = *[[:space:]/:-]* ]]; then
error "$(gettext "%s is not allowed to contain colons, forward slashes, hyphens or whitespace.")" "pkgver${type:+ in $type}"
return 1
fi
}

View file

@ -23,6 +23,8 @@ LIBMAKEPKG_LINT_PKGBUILD_PROVIDES_SH=1
LIBRARY=${LIBRARY:-'@libmakepkgdir@'}
source "$LIBRARY/lint_pkgbuild/pkgname.sh"
source "$LIBRARY/lint_pkgbuild/pkgver.sh"
source "$LIBRARY/util/message.sh"
source "$LIBRARY/util/pkgbuild.sh"
@ -31,30 +33,21 @@ lint_pkgbuild_functions+=('lint_provides')
lint_provides() {
local a list name provides_list ret=0
local provides_list provide name ver ret=0
provides_list=("${provides[@]}")
for a in "${arch[@]}"; do
array_build list "provides_$a"
provides_list+=("${list[@]}")
done
for name in "${pkgname[@]}"; do
if extract_function_variable "package_$name" provides 1 list; then
provides_list+=("${list[@]}")
fi
for a in "${arch[@]}"; do
if extract_function_variable "package_$name" "provides_$a" 1 list; then
provides_list+=("${list[@]}")
fi
done
done
get_pkgbuild_all_split_attributes provides provides_list
for provide in "${provides_list[@]}"; do
if [[ $provide == *['<>']* ]]; then
error "$(gettext "%s array cannot contain comparison (< or >) operators.")" "provides"
ret=1
continue
fi
name=${provide%%=*}
ver=${provide#*=}
lint_one_pkgname provides "$name" || ret=1
if [[ $ver != $provide ]]; then
check_pkgver "$ver" provides || ret=1
fi
done

View file

@ -116,6 +116,33 @@ get_pkgbuild_attribute() {
fi
}
get_pkgbuild_all_split_attributes() {
local attrname=$1 outputvar=$2 all_list list
if extract_global_variable "$attrname" 1 list; then
all_list+=("${list[@]}")
fi
for a in "${arch[@]}"; do
if extract_global_variable "${attrname}_$a" 1 list; then
all_list+=("${list[@]}")
fi
done
for name in "${pkgname[@]}"; do
if extract_function_variable "package_$name" "$attrname" 1 list; then
all_list+=("${list[@]}")
fi
for a in "${arch[@]}"; do
if extract_function_variable "package_$name" "${attrname}_$a" 1 list; then
all_list+=("${list[@]}")
fi
done
done
[[ ${all_list[@]} ]] && array_build "$outputvar" all_list
}
##
# usage : get_full_version()
# return : full version spec, including epoch (if necessary), pkgver, pkgrel