From da1e14c91cb42dbb3a0e0ac4ee968d0cbcd3c977 Mon Sep 17 00:00:00 2001 From: Ralf Wildenhues Date: Sat, 19 Apr 2008 18:24:48 +0200 Subject: [PATCH] Exploit shell arithmetic expansion and ${#var}. * libltdl/m4/libtool.m4 (_LT_CHECK_SHELL_FEATURES): Also check for arithmetic expansion, and ${#var}. (_LT_PROG_XSI_SHELLFNS): Define func_arith and func_len accordingly, falling back on 'expr'. Note that the argument to func_len may not start with a hyphen. In the pre-Posix fallback, take care not to rely on the exit status of the variable assignment (not portable), but set the length to $max_cmd_len instead. * libltdl/config/ltmain.m4sh (func_mode_link): Use func_arith and func_len throughout for integer arithmetic, fixing quadratical amount of counting for reloadable object and piecewise archive linking. Change all comparisons with max_cmd_len to test for smaller, non-equal length. * THANKS: Update. Suggested by Roland Mainz. Signed-off-by: Ralf Wildenhues --- ChangeLog | 17 +++++++ THANKS | 1 + libltdl/config/ltmain.m4sh | 99 +++++++++++++++++++++++++------------- libltdl/m4/libtool.m4 | 31 +++++++++++- 4 files changed, 114 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 63760ce10..d482b1652 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,22 @@ 2008-04-19 Ralf Wildenhues + Exploit shell arithmetic expansion and ${#var}. + * libltdl/m4/libtool.m4 (_LT_CHECK_SHELL_FEATURES): Also check + for arithmetic expansion, and ${#var}. + (_LT_PROG_XSI_SHELLFNS): Define func_arith and func_len + accordingly, falling back on 'expr'. Note that the argument to + func_len may not start with a hyphen. In the pre-Posix + fallback, take care not to rely on the exit status of the + variable assignment (not portable), but set the length to + $max_cmd_len instead. + * libltdl/config/ltmain.m4sh (func_mode_link): Use func_arith + and func_len throughout for integer arithmetic, fixing + quadratical amount of counting for reloadable object and + piecewise archive linking. Change all comparisons with + max_cmd_len to test for smaller, non-equal length. + * THANKS: Update. + Suggested by Roland Mainz. + * libltdl/config/ltmain.m4sh (func_mode_compile): Avoid redundant removal of old output files before compilation. Do not remove $obj until we have successfully grabbed the diff --git a/THANKS b/THANKS index 236bbaba0..3295b8793 100644 --- a/THANKS +++ b/THANKS @@ -120,6 +120,7 @@ Ralf Menzel menzel@ls6.cs.uni-dortmund.de Robert Ögren lists@roboros.com Roberto Bagnara bagnara@cs.unipr.it + Roland Mainz roland.mainz@nrubsig.org Sebastian Wilhelmi wilhelmi@ira.uka.de Simon Josefsson jas@extundo.com Stephan Kulow coolo@kde.org diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh index 8c5c45cfa..30e70eca0 100644 --- a/libltdl/config/ltmain.m4sh +++ b/libltdl/config/ltmain.m4sh @@ -2187,7 +2187,8 @@ func_extract_archives () while :; do case " $extracted_archives " in *" $my_xlib_u "*) - extracted_serial=`expr $extracted_serial + 1` + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac @@ -4656,7 +4657,8 @@ func_mode_link () # bleh windows case $host in *cygwin* | mingw*) - major=`expr $current - $age` + func_arith $current - $age + major=$func_arith_result versuffix="-$major" ;; esac @@ -5219,7 +5221,8 @@ func_mode_link () # case $version_type in darwin|linux|osf|windows|none) - current=`expr $number_major + $number_minor` + func_arith $number_major + $number_minor + current=$func_arith_result age="$number_minor" revision="$number_revision" ;; @@ -5229,7 +5232,8 @@ func_mode_link () age="0" ;; irix|nonstopux) - current=`expr $number_major + $number_minor` + func_arith $number_major + $number_minor + current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no @@ -5283,10 +5287,12 @@ func_mode_link () darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header - major=.`expr $current - $age` + func_arith $current - $age + major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... - minor_current=`expr $current + 1` + func_arith $current + 1 + minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; @@ -5303,10 +5309,11 @@ func_mode_link () irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then - major=`expr $current - $age` + func_arith $current - $age else - major=`expr $current - $age + 1` + func_arith $current - $age + 1 fi + major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; @@ -5317,8 +5324,10 @@ func_mode_link () # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do - iface=`expr $revision - $loop` - loop=`expr $loop - 1` + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done @@ -5328,20 +5337,24 @@ func_mode_link () ;; linux) - major=.`expr $current - $age` + func_arith $current - $age + major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) - major=.`expr $current - $age` + func_arith $current - $age + major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do - iface=`expr $current - $loop` - loop=`expr $loop - 1` + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result verstring="$verstring:${iface}.0" done @@ -5362,7 +5375,8 @@ func_mode_link () windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. - major=`expr $current - $age` + func_arith $current - $age + major=$func_arith_result versuffix="-$major" ;; @@ -6010,8 +6024,9 @@ EOF for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" - if len=`expr "X$cmd" : ".*"` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + func_len " $cmd" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then func_show_eval "$cmd" 'exit $?' skipped_export=false else @@ -6114,8 +6129,9 @@ EOF fi if test "X$skipped_export" != "X:" && - len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise @@ -6175,14 +6191,20 @@ EOF if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + # Loop over the list of objects to be linked. for obj in $save_libobjs do - eval test_cmds=\"$reload_cmds $objlist $last_robj\" + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result if test "X$objlist" = X || - { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len"; }; then - objlist="$objlist $obj" + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. @@ -6195,10 +6217,13 @@ EOF eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext - k=`expr $k + 1` + func_arith $k + 1 + k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=$obj - len=1 + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result fi done # Handle the remaining objects by creating one last @@ -6933,7 +6958,8 @@ EOF # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase - counter=`expr $counter + 1` + func_arith $counter + 1 + counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; @@ -6948,8 +6974,9 @@ EOF fi eval cmds=\"$old_archive_cmds\" - if len=`expr "X$cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts @@ -6959,18 +6986,23 @@ EOF objlist= concat_cmds= save_oldobjs=$oldobjs + oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 for obj in $save_oldobjs do - oldobjs="$objlist $obj" - objlist="$objlist $obj" - eval test_cmds=\"$old_archive_cmds\" - if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len"; then + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long @@ -6981,6 +7013,7 @@ EOF test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= + len=$len0 fi done RANLIB=$save_RANLIB diff --git a/libltdl/m4/libtool.m4 b/libltdl/m4/libtool.m4 index 1fc9ccf8d..cdab37837 100644 --- a/libltdl/m4/libtool.m4 +++ b/libltdl/m4/libtool.m4 @@ -7054,7 +7054,9 @@ m4_defun([_LT_CHECK_SHELL_FEATURES], xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,, ) >/dev/null 2>&1 \ + = c,a/b,, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) @@ -7173,6 +7175,19 @@ func_xform () func_xform_result=${1%.*}.lo } +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=$(( $[*] )) +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=${#1} +} + _LT_EOF ;; *) # Bourne compatible functions. @@ -7240,6 +7255,20 @@ func_xform () { func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` } + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "$[@]"` +} + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` +} + _LT_EOF esac -- 2.47.2