Date: Sat, 12 Oct 2013 19:52:27 +0000 (UTC) From: Devin Teske <dteske@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r256391 - head/usr.sbin/bsdconfig/share Message-ID: <201310121952.r9CJqRee025169@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dteske Date: Sat Oct 12 19:52:27 2013 New Revision: 256391 URL: http://svnweb.freebsd.org/changeset/base/256391 Log: Fix signed integer overflow detection in f_expand_number() of strings.subr. Approved by: re (glebius) Modified: head/usr.sbin/bsdconfig/share/strings.subr Modified: head/usr.sbin/bsdconfig/share/strings.subr ============================================================================== --- head/usr.sbin/bsdconfig/share/strings.subr Sat Oct 12 19:41:35 2013 (r256390) +++ head/usr.sbin/bsdconfig/share/strings.subr Sat Oct 12 19:52:27 2013 (r256391) @@ -341,17 +341,19 @@ f_shell_unescape() # # NOTE: Prefixes are case-insensitive. # -# Upon successful completion, the value 0 is returned (or stored to -# $var_to_set); otherwise -1. Reasons for a -1 return include: +# Upon successful completion, success status is returned; otherwise the number +# -1 is produced ($var_to_set set to -1 or if $var_to_set is NULL or missing) +# on standard output. In the case of failure, the error status will be one of: # -# Given $string contains no digits. -# An unrecognized prefix was given. -# Result too large to calculate. +# Status Reason +# 1 Given $string contains no digits +# 2 An unrecognized prefix was given +# 3 Result too large to calculate # f_expand_number() { local __string="$1" __var_to_set="$2" - local __cp __num + local __cp __num __bshift __maxinput # Remove any leading non-digits while :; do @@ -360,14 +362,14 @@ f_expand_number() [ "$__string" = "$__cp" ] && break done - # Return `-1' if string didn't contain any digits + # Produce `-1' if string didn't contain any digits if [ ! "$__string" ]; then if [ "$__var_to_set" ]; then setvar "$__var_to_set" -1 else echo -1 fi - return $FAILURE + return 1 # 1 = "Given $string contains no digits" fi # Store the numbers @@ -390,9 +392,23 @@ f_expand_number() [ "$__string" = "$__cp" ] && break done - # Test for invalid prefix + # + # Test for invalid prefix (and determine bitshift length) + # case "$__string" in - ""|[KkMmGgTtPpEe]*) : known prefix ;; + ""|[[:space:]]*) # Shortcut + if [ "$__var_to_set" ]; then + setvar "$__var_to_set" $__num + else + echo $__num + fi + return $SUCCESS ;; + [Kk]*) __bshift=10 ;; + [Mm]*) __bshift=20 ;; + [Gg]*) __bshift=30 ;; + [Tt]*) __bshift=40 ;; + [Pp]*) __bshift=50 ;; + [Ee]*) __bshift=60 ;; *) # Unknown prefix if [ "$__var_to_set" ]; then @@ -400,29 +416,23 @@ f_expand_number() else echo -1 fi - return $FAILURE + return 2 # 2 = "An unrecognized prefix was given" esac - # Multiply the number out - case "$__string" in - [Kk]) __num=$(( $__num * 1024 )) ;; - [Mm]) __num=$(( $__num * 1048576 )) ;; - [Gg]) __num=$(( $__num * 1073741824 )) ;; - [Tt]) __num=$(( $__num * 1099511627776 )) ;; - [Pp]) __num=$(( $__num * 1125899906842624 )) ;; - [Ee]) __num=$(( $__num * 1152921504606846976 )) ;; - esac - if [ $__num -le 0 ]; then - # Arithmetic overflow + # Determine if the wheels fall off + __maxinput=$(( 0x7fffffffffffffff >> $__bshift )) + if [ $__num -gt $__maxinput ]; then + # Input (before expanding) would exceed 64-bit signed int if [ "$__var_to_set" ]; then setvar "$__var_to_set" -1 else echo -1 fi - return $FAILURE + return 3 # 3 = "Result too large to calculate" fi - # Return the number + # Shift the number out and produce it + __num=$(( $__num << $__bshift )) if [ "$__var_to_set" ]; then setvar "$__var_to_set" $__num else
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201310121952.r9CJqRee025169>