From 840292befd6ad78e018f5ea16bec80e83d910071 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 2 Mar 2014 13:28:05 -0500 Subject: [PATCH] Disallow sizes with increasing unit size Things like 3B4T, 4B50B, 400 100 (meaning 4*1024**4+3, 54, and 500, respectively) are now disallowed. It is necessary to say 4T3B, 54B, 500 instead. I think this was confusing and error prone. As a special form, 400B 100 is allowed, i.e. "B" suffix is treated as different from "", although they mean the same thing. --- src/shared/util.c | 30 ++++++++++++++++-------------- src/test/test-util.c | 19 +++++++++++++++---- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/shared/util.c b/src/shared/util.c index 3164515a9..285a263cd 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2157,31 +2157,31 @@ int parse_size(const char *t, off_t base, off_t *size) { }; static const struct table iec[] = { - { "B", 1 }, - { "K", 1024ULL }, - { "M", 1024ULL*1024ULL }, - { "G", 1024ULL*1024ULL*1024ULL }, - { "T", 1024ULL*1024ULL*1024ULL*1024ULL }, - { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "T", 1024ULL*1024ULL*1024ULL*1024ULL }, + { "G", 1024ULL*1024ULL*1024ULL }, + { "M", 1024ULL*1024ULL }, + { "K", 1024ULL }, + { "B", 1 }, { "", 1 }, }; static const struct table si[] = { - { "B", 1 }, - { "K", 1000ULL }, - { "M", 1000ULL*1000ULL }, - { "G", 1000ULL*1000ULL*1000ULL }, - { "T", 1000ULL*1000ULL*1000ULL*1000ULL }, - { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL }, { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL }, + { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL }, + { "T", 1000ULL*1000ULL*1000ULL*1000ULL }, + { "G", 1000ULL*1000ULL*1000ULL }, + { "M", 1000ULL*1000ULL }, + { "K", 1000ULL }, + { "B", 1 }, { "", 1 }, }; const struct table *table; const char *p; unsigned long long r = 0; - unsigned n_entries; + unsigned n_entries, start_pos = 0; assert(t); assert(base == 1000 || base == 1024); @@ -2235,7 +2235,7 @@ int parse_size(const char *t, off_t base, off_t *size) { e += strspn(e, WHITESPACE); - for (i = 0; i < n_entries; i++) + for (i = start_pos; i < n_entries; i++) if (startswith(e, table[i].suffix)) { unsigned long long tmp; if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor) @@ -2249,6 +2249,8 @@ int parse_size(const char *t, off_t base, off_t *size) { return -ERANGE; p = e + strlen(table[i].suffix); + + start_pos = i + 1; break; } diff --git a/src/test/test-util.c b/src/test/test-util.c index 74f83a262..1de06dbda 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -460,21 +460,32 @@ static void test_parse_size(void) { assert_se(parse_size("3.0 K", 1024, &bytes) == 0); assert_se(bytes == 3*1024); - assert_se(parse_size("3. 0 K", 1024, &bytes) == 0); - assert_se(bytes == 3); + assert_se(parse_size("3. 0 K", 1024, &bytes) == -EINVAL); assert_se(parse_size(" 4 M 11.5K", 1024, &bytes) == 0); assert_se(bytes == 4*1024*1024 + 11 * 1024 + 512); - assert_se(parse_size("3B3.5G", 1024, &bytes) == 0); + assert_se(parse_size("3B3.5G", 1024, &bytes) == -EINVAL); + + assert_se(parse_size("3.5G3B", 1024, &bytes) == 0); assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3); - assert_se(parse_size("3B3G4T", 1024, &bytes) == 0); + assert_se(parse_size("3.5G 4B", 1024, &bytes) == 0); + assert_se(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 4); + + assert_se(parse_size("3B3G4T", 1024, &bytes) == -EINVAL); + + assert_se(parse_size("4T3G3B", 1024, &bytes) == 0); + assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3); + + assert_se(parse_size(" 4 T 3 G 3 B", 1024, &bytes) == 0); assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3); assert_se(parse_size("12P", 1024, &bytes) == 0); assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024); + assert_se(parse_size("12P12P", 1024, &bytes) == -EINVAL); + assert_se(parse_size("3E 2P", 1024, &bytes) == 0); assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024); -- 2.30.2