Package: initramfs-tools-core Version: 0.123 Severity: minor Tags: patch Congratulations on initramfs-tools version 0.123! Many bugs in version 0.120 have been fixed in this version. However, it appears that the parse_numeric function, while improved over the 0.120 version, still doesn't handle the general case of a composite device number. It seems it will only handle 8 hex digits or less correctly.
I have submitted a patch for your consideration. The patch will accommodate the general case of a composite device number of up to 16 hex digits (the limit). It also tightens up some other error checking corner cases. Respectfully submitted, -- .''`. Stephen Powell <zlinux...@fastmail.com> : :' : `. `'` `-
--- a/functions 2016-01-21 18:33:59.000000000 -0500 +++ b/functions 2016-03-24 08:09:11.000000000 -0400 @@ -128,14 +128,28 @@ # lilo compatibility parse_numeric() { - case $1 in + case "$1" in *:*) # Does it match /[0-9]*:[0-9]*/? - minor=${1#*:} - major=${1%:*} - case $major$minor in + minor="${1#*:}" # Everything after the first colon. + major="${1%%:*}" # Everything before the first colon. + [ X"$major" = X ] && return # major is null. + [ X"$minor" = X ] && return # minor is null. + case "$major$minor" in *[!0-9]*) - # No. + # major or minor contains a non-numeric character. + return + ;; + esac + case "$major" in + 0?*) + # major has a leading zero. + return + ;; + esac + case "$minor" in + 0?*) + # minor has a leading zero. return ;; esac @@ -146,9 +160,56 @@ ;; *) # [A-Fa-f0-9]* - value=$(( 0x${1} )) - minor=$(( (${value} & 0xff) | (${value} >> 12) & 0xfff00 )) - major=$(( (${value} >> 8) & 0xfff )) + case "$1" in + 0?*) + # Composite device number has a leading zero. + return + ;; + esac + [ ${#1} -gt 16 ] && return # More than 16 hex digits. + # + # 16 hex digits, with leading zeros suppressed. + # Format is MMMMMmmmmmmMMMmm, where the "M"s are the hex + # digits of the major device number and the "m"s are the + # hex digits of the minor device number. + # + # Note: the shell uses 64-bit two's complement signed binary + # integer arithmetic internally when evaluating arithmetic + # expressions, even on 32-bit platforms such as i386. Bitwise + # shift operations are arithmetic shifts, not logical shifts. + # Only the right-most 63 bits participate in a shift operation. + # The left-most bit, the sign bit, does not participate in + # the shift operation and remains unchanged. For a shift + # left operation, bits shifted out of the left-most bit + # position which participates in the shift are lost; and zeros + # are shifted in on the right. Arithmetic overflow occurs + # if any bits unlike the sign bit are shifted out of the + # left-most bit position which participates in the shift. + # (However, arithmetic overflow is ignored.) For a shift + # right operation, bits shifted out of the right-most bit + # position are lost; and copies of the sign bit are shifted + # in on the left. All 64 bit positions, including the sign + # bit, participate in bitwise "and" and bitwise "or" + # operations. + # + # Hexadecimal constants are treated as padded on the left + # with zeros, if needed, or truncated on the left, if needed, + # to make 16 digits. If the left-most digit, after padding + # or truncating if needed, is in the range 8-f, inclusive, + # then the number is treated as negative, in two's complement + # form. Otherwise, the number is treated as positive (or zero + # if all digits are zero). + # + # For the three operators used in the expressions below, + # the bitwise shift right operator (>>) has the highest + # priority, followed by the bitwise "and" operator (&), + # followed by the bitwise "or" operator (|). Therefore, the + # default order of operations is correct; and no parentheses + # are needed in the expressions themselves. + # + devno=$(( 0x$1 )) + major=$(( devno >> 8 & 0xfff | devno >> 32 & 0xfffff000 )) + minor=$(( devno & 0xff | devno >> 12 & 0xffffff00 )) ;; esac