summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian C. Lane <bcl@redhat.com>2023-03-03 14:35:22 -0800
committerBrian C. Lane <bcl@redhat.com>2023-03-17 16:12:41 -0700
commit3f6b723a7d610d98afb0c9d0cfefe4700712e4db (patch)
tree841634a8bff641892b636e49e0cae210abcdd8e0
parentd272bb5b5343fd288a204314654a7fbaea84528d (diff)
downloadparted-3f6b723a7d610d98afb0c9d0cfefe4700712e4db.tar.gz
parted: Fix ending sector location when using kibi IEC suffix
This fixes a bug when using KiB to specify the ending location of a partition. It was not subtracting 1s like it does with the other units because it was looking for a 'k' not a 'K'. This also fixes a quirk of the suffix checking code, it would check for matching case, but converting to the actual IEC value was case insensitive. This now uses common functions for the matching so that case doesn't matter. It also adds tests to check for the fix. The only change in behavior is that using KiB to specify the ending location of a partition will now correctly create the end 1s lower than the specified location like it does for MiB, GiB, etc.
-rw-r--r--parted/parted.c29
-rw-r--r--tests/t0207-IEC-binary-notation.sh31
-rw-r--r--tests/t0208-mkpart-end-in-IEC.sh2
3 files changed, 51 insertions, 11 deletions
diff --git a/parted/parted.c b/parted/parted.c
index 84187b7..84465d5 100644
--- a/parted/parted.c
+++ b/parted/parted.c
@@ -583,16 +583,27 @@ void _strip_trailing_spaces(char *str)
str[i]='\0';
}
-/* Return true, if str ends with [kMGTPEZY]iB, i.e. IEC units. */
+/* Return true if the unit is one of the supported IEC unit values */
+static bool
+_is_unit_IEC(const PedUnit unit) {
+ return (unit == PED_UNIT_KIBIBYTE) || (unit == PED_UNIT_MEBIBYTE) ||
+ (unit == PED_UNIT_GIBIBYTE) || (unit == PED_UNIT_TEBIBYTE);
+}
+
+/* Return true, if str ends with IEC units. */
static bool
_string_ends_with_iec_unit(const char *str)
{
- /* 3 characters for the IEC unit and at least 1 digit */
- if (!str || strlen(str) < 4)
- return false;
+ /* 3 characters for the IEC unit and at least 1 digit */
+ if (!str || strlen(str) < 4)
+ return false;
- char const *p = str + strlen(str) - 3;
- return strchr ("kMGTPEZY", *p) && c_strcasecmp (p+1, "iB") == 0;
+ char const *p = str + strlen(str) - 3;
+ PedUnit unit = ped_unit_get_by_name(p);
+ if (unit == -1) {
+ return false;
+ }
+ return _is_unit_IEC(unit);
}
/* Return true if str ends with explicit unit identifier.
@@ -612,7 +623,7 @@ _string_has_unit_suffix(const char *str)
return false;
}
-/* If the selected unit is one of kiB, MiB, GiB or TiB and the partition is not
+/* If the selected unit is one of KiB, MiB, GiB or TiB and the partition is not
* only 1 sector long, then adjust the end so that it is one sector before the
* given position. Also adjust range_end accordingly. Thus next partition can
* start immediately after this one.
@@ -636,9 +647,7 @@ _adjust_end_if_iec (PedSector* start, PedSector* end,
_strip_trailing_spaces(end_input);
PedUnit unit = ped_unit_get_default();
if (_string_ends_with_iec_unit(end_input) ||
- (!_string_has_unit_suffix(end_input) &&
- ((unit == PED_UNIT_KIBIBYTE) || (unit == PED_UNIT_MEBIBYTE) ||
- (unit == PED_UNIT_GIBIBYTE) || (unit == PED_UNIT_TEBIBYTE)))) {
+ (!_string_has_unit_suffix(end_input) && _is_unit_IEC(unit))) {
*end -= 1;
range_end->start -= 1;
range_end->end -= 1;
diff --git a/tests/t0207-IEC-binary-notation.sh b/tests/t0207-IEC-binary-notation.sh
index d9bbad6..b8a789e 100644
--- a/tests/t0207-IEC-binary-notation.sh
+++ b/tests/t0207-IEC-binary-notation.sh
@@ -28,6 +28,7 @@ parted --align=none -s $dev mklabel gpt mkpart p1 $((64*1024))B $((1024*1024-$ss
compare /dev/null err || fail=1
parted -m -s $dev u s p > exp || fail=1
+# Test using MiB
rm $dev
dd if=/dev/null of=$dev bs=$ss seek=$n_sectors || fail=1
parted --align=none -s $dev mklabel gpt mkpart p1 64KiB 1MiB \
@@ -37,4 +38,34 @@ parted -m -s $dev u s p > out || fail=1
compare exp out || fail=1
+# Test using lower case kib and mib
+rm $dev
+dd if=/dev/null of=$dev bs=$ss seek=$n_sectors || fail=1
+parted --align=none -s $dev mklabel gpt mkpart p1 64kib 1mib \
+ > err 2>&1 || fail=1
+compare /dev/null err || fail=1
+parted -m -s $dev u s p > out || fail=1
+
+compare exp out || fail=1
+
+# Test using KiB
+rm $dev
+dd if=/dev/null of=$dev bs=$ss seek=$n_sectors || fail=1
+parted --align=none -s $dev mklabel gpt mkpart p1 64KiB 1024KiB \
+ > err 2>&1 || fail=1
+compare /dev/null err || fail=1
+parted -m -s $dev u s p > out || fail=1
+
+compare exp out || fail=1
+
+# Test using kiB
+rm $dev
+dd if=/dev/null of=$dev bs=$ss seek=$n_sectors || fail=1
+parted --align=none -s $dev mklabel gpt mkpart p1 64kiB 1024kiB \
+ > err 2>&1 || fail=1
+compare /dev/null err || fail=1
+parted -m -s $dev u s p > out || fail=1
+
+compare exp out || fail=1
+
Exit $fail
diff --git a/tests/t0208-mkpart-end-in-IEC.sh b/tests/t0208-mkpart-end-in-IEC.sh
index 118ec72..a3db2c3 100644
--- a/tests/t0208-mkpart-end-in-IEC.sh
+++ b/tests/t0208-mkpart-end-in-IEC.sh
@@ -25,7 +25,7 @@ dev=dev-file
dd if=/dev/null of=$dev bs=1M seek=$n_mbs || fail=1
# create 1st partition
-parted --align=none -s $dev mklabel gpt mkpart p1 1MiB 2MiB > err 2>&1 || fail=1
+parted --align=none -s $dev mklabel gpt mkpart p1 1MiB 2048KiB > err 2>&1 || fail=1
compare /dev/null err || fail=1 # expect no output
#parted -m -s $dev u s p > exp || fail=1