d747d1a8fe
- tests: Fix formatting and snprintf warnings in tests. (bcl) - ui: Add checks for prompt being NULL (bcl) - strlist: Handle realloc error in wchar_to_str (bcl) - libparted: Fix potential NULL dereference in ped_disk_next_partition (bcl) - filesys: Check for null from close_fn (bcl)
147 lines
5.4 KiB
Diff
147 lines
5.4 KiB
Diff
From 3f6b723a7d610d98afb0c9d0cfefe4700712e4db Mon Sep 17 00:00:00 2001
|
|
From: "Brian C. Lane" <bcl@redhat.com>
|
|
Date: Fri, 3 Mar 2023 14:35:22 -0800
|
|
Subject: [PATCH] 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.
|
|
---
|
|
parted/parted.c | 29 ++++++++++++++++++----------
|
|
tests/t0207-IEC-binary-notation.sh | 31 ++++++++++++++++++++++++++++++
|
|
tests/t0208-mkpart-end-in-IEC.sh | 2 +-
|
|
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
|
|
|
|
--
|
|
2.39.2
|
|
|