Author: branden Date: 2003-10-21 23:27:07 -0500 (Tue, 21 Oct 2003) New Revision: 692
Modified: trunk/debian/changelog trunk/debian/shell-lib.sh Log: Perform further overhauls and robustification to shell-lib.sh. + reject_nondigits(),reject_whitespace(),reject_unlikely_path_chars(): new functions for validating shell function arguments and environment variables not under this file's control + message(),message_nonl(): call reject_nondigits to validate $COLUMNS + create more coherent functions for user communication; drop debugmsg() and errormsg(), and create three levels of communication: fatal errors, warnings, and chatter - observe(): used for any user communication that is not fairly important; not seen by default, but visible when the $DEBUG_XFREE86_PACKAGE variable is set in the environment to a non-null value; also someday when dpkg supports logging, we'll sent these messages its way - warn(): new function, used for communicating important information - die(): new function, used for hideous death screams + internal_error(): renamed from internal_errormsg(); also identifies itself explicitly in output + usage_error(): renamed from usage_errormsg(); also identifies itself explicitly in output + maplink(): use internal_error() instead of internal_errormsg() + analyze_path(),find_culprits: - explicitly scope local variables and make them lowercase - call reject_whitespace() on arguments + readlink(): quote shell variable in internal Perl implementation + check_symlinks_and_warn(),check_symlinks_and_bomb: - use usage_error() instead of usage_errormsg() - use observe() instead of debugmsg() - use die() instead of message() + font_update(): - explicitly scope local variables and make them lowercase - call reject_unlikely_path_chars() on shell variables used - confirm that the font directory being operated exists before attempting operations on it - don't let failures of a font update command be fatal to the package; if a command fails, warn() about it instead + remove_conffile_prepare(),remove_conffile_commit(), remove_conffile_rollback(): use usage_error() instead of usage_errormsg() + remove_conffile_rollback(): correct self-reference in error message (cut and paste error) + safe_debconf(): - use usage_error() instead of usage_errormsg() - use observe() instead of debugmsg() - debian/shell-lib.sh Modified: trunk/debian/changelog =================================================================== --- trunk/debian/changelog 2003-10-22 03:42:24 UTC (rev 691) +++ trunk/debian/changelog 2003-10-22 04:27:07 UTC (rev 692) @@ -68,8 +68,52 @@ xdm) must be configured every time xdm's postinst runs. - debian/xdm.postinst.in - -- Branden Robinson <[EMAIL PROTECTED]> Tue, 21 Oct 2003 22:41:16 -0500 + * Perform further overhauls and robustification to shell-lib.sh. + + reject_nondigits(),reject_whitespace(),reject_unlikely_path_chars(): new + functions for validating shell function arguments and environment + variables not under this file's control + + message(),message_nonl(): call reject_nondigits to validate $COLUMNS + + create more coherent functions for user communication; drop debugmsg() + and errormsg(), and create three levels of communication: fatal errors, + warnings, and chatter + - observe(): used for any user communication that is not fairly + important; not seen by default, but visible when the + $DEBUG_XFREE86_PACKAGE variable is set in the environment to a non-null + value; also someday when dpkg supports logging, we'll sent these + messages its way + - warn(): new function, used for communicating important information + - die(): new function, used for hideous death screams + + internal_error(): renamed from internal_errormsg(); also identifies + itself explicitly in output + + usage_error(): renamed from usage_errormsg(); also identifies itself + explicitly in output + + maplink(): use internal_error() instead of internal_errormsg() + + analyze_path(),find_culprits: + - explicitly scope local variables and make them lowercase + - call reject_whitespace() on arguments + + readlink(): quote shell variable in internal Perl implementation + + check_symlinks_and_warn(),check_symlinks_and_bomb: + - use usage_error() instead of usage_errormsg() + - use observe() instead of debugmsg() + - use die() instead of message() + + font_update(): + - explicitly scope local variables and make them lowercase + - call reject_unlikely_path_chars() on shell variables used + - confirm that the font directory being operated exists before attempting + operations on it + - don't let failures of a font update command be fatal to the package; if + a command fails, warn() about it instead + + remove_conffile_prepare(),remove_conffile_commit(), + remove_conffile_rollback(): use usage_error() instead of usage_errormsg() + + remove_conffile_rollback(): correct self-reference in error message (cut + and paste error) + + safe_debconf(): + - use usage_error() instead of usage_errormsg() + - use observe() instead of debugmsg() + - debian/shell-lib.sh + -- Branden Robinson <[EMAIL PROTECTED]> Tue, 21 Oct 2003 23:25:38 -0500 + xfree86 (4.2.1-12.1) unstable; urgency=low * Fix typo in xlibs preinst. Closes: #213774, #213776 Modified: trunk/debian/shell-lib.sh =================================================================== --- trunk/debian/shell-lib.sh 2003-10-22 03:42:24 UTC (rev 691) +++ trunk/debian/shell-lib.sh 2003-10-22 04:27:07 UTC (rev 692) @@ -42,34 +42,98 @@ message;\ exit 1" HUP INT QUIT TERM +reject_nondigits () { + # syntax: reject_nondigits [ operand ... ] + # + # scan operands (typically shell variables whose values cannot be trusted) for + # characters other than decimal digits and barf if any are found + while [ -n "$1" ]; do + # does the operand contain anything but digits? + if ! expr "$1" : "[[:digit:]]\+$" > /dev/null 2>&1; then + # can't use die(), because it wraps message() which wraps this function + echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_nondigits() encountered" \ + "possibly malicious garbage \"$1\"" >&2 + exit $SHELL_LIB_THROWN_ERROR + fi + shift + done +} + +reject_whitespace () { + # syntax: reject_whitespace [ operand ] + # + # scan operand (typically a shell variable whose value cannot be trusted) for + # whitespace characters and barf if any are found + if [ -n "$1" ]; then + # does the operand contain any whitespace? + if expr "$1" : "[[:space:]]" > /dev/null 2>&1; then + # can't use die(), because I want to avoid forward references + echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_whitespace() encountered" \ + "possibly malicious garbage \"$1\"" >&2 + exit $SHELL_LIB_THROWN_ERROR + fi + fi +} + +reject_unlikely_path_chars () { + # syntax: reject_unlikely_path_chars [ operand ... ] + # + # scan operands (typically shell variables whose values cannot be trusted) for + # characters unlikely to be seen in a path and which the shell might + # interpret and barf if any are found + while [ -n "$1" ]; do + # does the operand contain any funny characters? + if ! expr "$1" : '[!$&()*;<>?[]|]$' > /dev/null 2>&1; then + # can't use die(), because I want to avoid forward references + echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_unlikely_path_chars()" \ + "encountered possibly malicious garbage \"$1\"" >&2 + exit $SHELL_LIB_THROWN_ERROR + fi + shift + done +} + message () { # pretty-print messages of arbitrary length + reject_nondigits "$COLUMNS" echo "$*" | fold -s -w ${COLUMNS:-80} >&2 } message_nonl () { # pretty-print messages of arbitrary length (no trailing newline) + reject_nondigits "$COLUMNS" echo -n "$*" | fold -s -w ${COLUMNS:-80} >&2 } -debugmsg () { - # syntax: debug_echo message ... +observe () { + # syntax: observe message ... # - # issue debugging message + # issue observational message suitable for logging someday when support for + # it exists in dpkg if [ -n "$DEBUG_XFREE86_PACKAGE" ]; then - message "$THIS_PACKAGE $THIS_SCRIPT debug: $*" + message "$THIS_PACKAGE $THIS_SCRIPT note: $*" fi } -errormsg () { - # exit script with error +warn () { + # syntax: warn message ... + # + # issue warning message suitable for logging someday when support for + # it exists in dpkg; also send to standard error + message "$THIS_PACKAGE $THIS_SCRIPT warning: $*" +} + +die () { + # syntax: die message ... + # + # exit script with error message message "$THIS_PACKAGE $THIS_SCRIPT error: $*" exit $SHELL_LIB_THROWN_ERROR } -internal_errormsg () { +internal_error () { # exit script with error; essentially a "THIS SHOULD NEVER HAPPEN" message - message "$*" + message "internal error: $*" if [ -n "$OFFICIAL_BUILD" ]; then message "Please report a bug in the $THIS_SCRIPT script of the" \ "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \ @@ -84,8 +148,8 @@ exit $SHELL_LIB_INTERNAL_ERROR } -usage_errormsg () { - message "$*" +usage_error () { + message "usage error: $*" message "Please report a bug in the $THIS_SCRIPT script of the" \ "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \ "Tracking System. Include all messages above that mention the" \ @@ -98,6 +162,7 @@ exit $SHELL_LIB_USAGE_ERROR } + maplink () { # returns what symlink should point to; i.e., what the "sane" answer is # Keep this in sync with the debian/*.links files. @@ -120,7 +185,7 @@ /usr/bin/rstartd) echo ../X11R6/bin/rstartd ;; /usr/include/X11) echo ../X11R6/include/X11 ;; /usr/lib/X11) echo ../X11R6/lib/X11 ;; - *) internal_errormsg "ERROR: maplink() called with unknown path \"$1\"" ;; + *) internal_error "maplink() called with unknown path \"$1\"" ;; esac } @@ -129,16 +194,20 @@ # ls -dl on each component, cumulatively; i.e. # analyze_path /usr/X11R6/bin -> ls -dl /usr /usr/X11R6 /usrX11R6/bin # Thanks to Randolph Chung for this clever hack. + + local f g + while [ -n "$1" ]; do - G= + reject_whitespace "$1" + g= message "Analyzing $1:" - for F in $(echo "$1" | tr / \ ); do - if [ -e /$G$F ]; then - ls -dl /$G$F /$G$F.dpkg-* 2> /dev/null || true - G=$G$F/ + for f in $(echo "$1" | tr / \ ); do + if [ -e /$g$f ]; then + ls -dl /$g$f /$g$f.dpkg-* 2> /dev/null || true + g=$g$f/ else - message "/$G$F: nonexistent; directory contents of /$G:" - ls -l /$G + message "/$g$f: nonexistent; directory contents of /$g:" + ls -l /$g break fi done @@ -147,20 +216,23 @@ } find_culprits () { + local f p dpkg_info_dir possible_culprits smoking_guns bad_packages package + + reject_whitespace "$1" message "Searching for overlapping packages..." - DPKG_INFO_DIR=/var/lib/dpkg/info - if [ -d $DPKG_INFO_DIR ]; then - if [ "$(echo $DPKG_INFO_DIR/*.list)" != "$DPKG_INFO_DIR/*.list" ]; then - POSSIBLE_CULPRITS=$(ls -1 $DPKG_INFO_DIR/*.list | egrep -v \ + dpkg_info_dir=/var/lib/dpkg/info + if [ -d $dpkg_info_dir ]; then + if [ "$(echo $dpkg_info_dir/*.list)" != "$dpkg_info_dir/*.list" ]; then + possible_culprits=$(ls -1 $dpkg_info_dir/*.list | egrep -v \ "(xbase-clients|xfree86-common|xfs|xlibs)") - SMOKING_GUNS=$(grep -l "$1" $POSSIBLE_CULPRITS) - if [ -n "$SMOKING_GUNS" ]; then - BAD_PACKAGES=$(printf "\\n") - for F in $SMOKING_GUNS; do + smoking_guns=$(grep -l "$1" $possible_culprits) + if [ -n "$smoking_guns" ]; then + bad_packages=$(printf "\\n") + for f in $smoking_guns; do # too bad you can't nest parameter expansion voodoo - P=${F%*.list} # strip off the trailing ".list" - PACKAGE=${P##*/} # strip off the directories - BAD_PACKAGES=$(printf "%s\n%s" "$BAD_PACKAGES" "$PACKAGE") + p=${f%*.list} # strip off the trailing ".list" + package=${p##*/} # strip off the directories + bad_packages=$(printf "%s\n%s" "$bad_packages" "$package") done message "The following packages appear to have file overlaps" \ "with the XFree86 packages; these packages are either very" \ @@ -173,15 +245,15 @@ "file overlap, please file a bug against that package with the" \ "Debian Bug Tracking System. You may want to refer the package" \ "maintainer to section 12.8 of the Debian Policy manual." - message "The overlapping packages are: $BAD_PACKAGES" + message "The overlapping packages are: $bad_packages" else message "no overlaps found." fi else - message "cannot search; no matches for $DPKG_INFO_DIR/*.list." + message "cannot search; no matches for $dpkg_info_dir/*.list." fi else - message "cannot search; $DPKG_INFO_DIR does not exist." + message "cannot search; $dpkg_info_dir does not exist." fi } @@ -191,7 +263,7 @@ "1.13.1 or later of the debianutils package." readlink () { # returns what symlink in $1 actually points to - perl -e '$l = shift; exit 1 unless -l $l; $r = readlink $l; exit 1 unless $r; print "$r\n"' $1 + perl -e '$l = shift; exit 1 unless -l $l; $r = readlink $l; exit 1 unless $r; print "$r\n"' "$1" } fi @@ -207,8 +279,8 @@ # validate arguments if [ $# -lt 1 ]; then - usage_errormsg "check_symlinks_and_warn() called with wrong number of" \ - "arguments; expected at least 1, got $#" + usage_error "check_symlinks_and_warn() called with wrong number of" \ + "arguments; expected at least 1, got $#" exit $SHELL_LIB_USAGE_ERROR fi @@ -216,12 +288,12 @@ symlink="$1" if [ -L "$symlink" ]; then if [ "$(maplink "$symlink")" != "$(readlink "$symlink")" ]; then - debugmsg "$symlink symbolic link points to wrong location" \ - "$(readlink "$symlink"); removing" + observe "$symlink symbolic link points to wrong location" \ + "$(readlink "$symlink"); removing" rm "$symlink" fi elif [ -e "$symlink" ]; then - errmsg="$symlink exists and is not a symbolic link. This package cannot" + errmsg="$symlink exists and is not a symbolic link; this package cannot" errmsg="be installed until this" if [ -f "$symlink" ]; then errmsg="$errmsg file" @@ -230,9 +302,8 @@ else errmsg="$errmsg thing" fi - errmsg="$errmsg is removed." - message "$errmsg" - errormsg "Aborting installation of $THIS_PACKAGE package." + errmsg="$errmsg is removed" + die "$errmsg" fi shift done @@ -249,8 +320,8 @@ # validate arguments if [ $# -lt 1 ]; then - usage_errormsg "check_symlinks_and_bomb() called with wrong number of" \ - "arguments; expected at least 1, got $#" + usage_error "check_symlinks_and_bomb() called with wrong number of" + "arguments; expected at least 1, got $#" exit $SHELL_LIB_USAGE_ERROR fi @@ -260,15 +331,15 @@ if [ -L "$symlink" ]; then if [ "$(maplink "$symlink")" != "$(readlink "$symlink")" ]; then problem=yes - errormsg "$symlink symbolic link points to wrong location" \ - "$(readlink "$symlink")" + die "$symlink symbolic link points to wrong location" \ + "$(readlink "$symlink")" fi elif [ -e "$symlink" ]; then problem=yes - errormsg "$symlink is not a symbolic link" + die "$symlink is not a symbolic link" else problem=yes - errormsg "$symlink symbolic link does not exist" + die "$symlink symbolic link does not exist" fi if [ -n "$problem" ]; then analyze_path "$symlink" "$(readlink "$symlink")" @@ -281,35 +352,44 @@ font_update () { # run $UPDATECMDS in $FONTDIRS + + local dir cmd shortcmd + if [ -z "$UPDATECMDS" ]; then - internal_errormsg "ERROR: Some chucklehead called font_update() without" \ - "setting \$UPDATECMDS." + usage_error "font_update() called but \$UPDATECMDS not set" fi if [ -z "$FONTDIRS" ]; then - internal_errormsg "ERROR: Some chucklehead called font_update() without" \ - "setting \$FONTDIRS." + usage_error "font_update() called but \$FONTDIRS not set" fi - for DIR in $FONTDIRS; do - for CMD in $UPDATECMDS; do - if which $CMD > /dev/null 2>&1; then - SHORTCMD=$(basename $CMD) - message_nonl "Running $SHORTCMD in $DIR font directory..." - if [ "$SHORTCMD" = "xftcache" ]; then - if [ "$DIR" = "Speedo" ]; then - # do nothing; xftcache SEGVs (*sometimes*) when asked to process the - # Speedo directory - CMD=: + + reject_unlikely_path_chars "$UPDATECMDS" + reject_unlikely_path_chars "$FONTDIRS" + + for dir in $FONTDIRS; do + if [ -d "$dir" ]; then + for cmd in $UPDATECMDS; do + if which "$cmd" > /dev/null 2>&1; then + shortcmd=$(basename $cmd) + observe "running $shortcmd in $dir font directory" + if [ "$shortcmd" = "xftcache" ]; then + if [ "$dir" = "Speedo" ]; then + # do nothing; xftcache SEGVs (*sometimes*) when asked to process + # the Speedo directory + CMD=: + fi + # KLUDGE: xftcache needs to be handed the full path; the command + # goes away anyway in XFree86 4.3.0 + dir="/usr/X11R6/lib/X11/fonts/$dir" fi - # KLUDGE: xftcache needs to be handed the full path; the command goes - # away anyway in XFree86 4.3.0 - DIR=/usr/X11R6/lib/X11/fonts/$DIR + $cmd $dir || warn "$cmd $dir failed; font directory data may not" \ + "be up to date" + else + warn "$cmd not found; not updating $dir font directory data" fi - $CMD $DIR - message "done." - else - message "Note: $CMD not found; not updating $DIR font directory data." - fi - done + done + else + warn "$dir is not a directory; not updating corresponding font data" + fi done } @@ -331,8 +411,8 @@ # validate arguments if [ $# -lt 2 ]; then - usage_errormsg "remove_conffile_prepare() called with wrong number of" \ - "arguments; expected at least 2, got $#" + usage_error "remove_conffile_prepare() called with wrong number of" \ + "arguments; expected at least 2, got $#" exit $SHELL_LIB_USAGE_ERROR fi @@ -367,8 +447,8 @@ # validate arguments if [ $# -ne 1 ]; then - usage_errormsg "remove_conffile_commit() called with wrong number of" \ - "arguments; expected 1, got $#" + usage_error "remove_conffile_commit() called with wrong number of" \ + "arguments; expected 1, got $#" exit $SHELL_LIB_USAGE_ERROR fi @@ -393,8 +473,8 @@ # validate arguments if [ $# -ne 1 ]; then - usage_errormsg "remove_conffile_commit() called with wrong number of" \ - "arguments; expected 1, got $#" + usage_error "remove_conffile_rollback() called with wrong number of" \ + "arguments; expected 1, got $#" exit $SHELL_LIB_USAGE_ERROR fi @@ -417,15 +497,15 @@ # validate arguments if [ $# -lt 1 ]; then - usage_errormsg "safe_debconf() called with wrong number of arguments;" \ - "expected at least 1, got $#" + usage_error "safe_debconf() called with wrong number of arguments;" \ + "expected at least 1, got $#" exit $SHELL_LIB_USAGE_ERROR fi "$@" || retval=$? if [ ${retval:-0} -ne 0 ]; then - debugmsg "command \"$*\" exited with status $retval" + observe "command \"$*\" exited with status $retval" fi } -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]