[systemd-commits] 2 commits - src/shared src/test

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Sun Mar 2 10:59:20 PST 2014


 src/shared/util.c    |   54 +++++++++++++++++++++++++++++++++++---------------
 src/test/test-util.c |   55 +++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 87 insertions(+), 22 deletions(-)

New commits:
commit 840292befd6ad78e018f5ea16bec80e83d910071
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Sun Mar 2 13:28:05 2014 -0500

    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.

diff --git a/src/shared/util.c b/src/shared/util.c
index 3164515..285a263 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 74f83a2..1de06db 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);
 

commit 9480794b277b5ce33e467578ed669996df576bb9
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Sun Mar 2 00:05:16 2014 -0500

    Allow fractional parts in disk sizes
    
    It seems natural to be able to say SystemMaxUsage=1.5G.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1047568

diff --git a/src/shared/util.c b/src/shared/util.c
index 5cb598c..3164515 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -2198,6 +2198,8 @@ int parse_size(const char *t, off_t base, off_t *size) {
         p = t;
         do {
                 long long l;
+                unsigned long long l2;
+                double frac = 0;
                 char *e;
                 unsigned i;
 
@@ -2213,14 +2215,32 @@ int parse_size(const char *t, off_t base, off_t *size) {
                 if (e == p)
                         return -EINVAL;
 
+                if (*e == '.') {
+                        e++;
+                        if (*e >= '0' && *e <= '9') {
+                                char *e2;
+
+                                /* strotoull itself would accept space/+/- */
+                                l2 = strtoull(e, &e2, 10);
+
+                                if (errno == ERANGE)
+                                        return -errno;
+
+                                /* Ignore failure. E.g. 10.M is valid */
+                                frac = l2;
+                                for (; e < e2; e++)
+                                        frac /= 10;
+                        }
+                }
+
                 e += strspn(e, WHITESPACE);
 
                 for (i = 0; i < n_entries; i++)
                         if (startswith(e, table[i].suffix)) {
                                 unsigned long long tmp;
-                                if ((unsigned long long) l > ULLONG_MAX / table[i].factor)
+                                if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
                                         return -ERANGE;
-                                tmp = l * table[i].factor;
+                                tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
                                 if (tmp > ULLONG_MAX - r)
                                         return -ERANGE;
 
diff --git a/src/test/test-util.c b/src/test/test-util.c
index b718206..74f83a2 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -30,6 +30,7 @@
 #include "strv.h"
 #include "def.h"
 #include "fileio.h"
+#include "conf-parser.h"
 
 static void test_streq_ptr(void) {
         assert_se(streq_ptr(NULL, NULL));
@@ -441,17 +442,32 @@ static void test_parse_size(void) {
         assert_se(parse_size("111", 1024, &bytes) == 0);
         assert_se(bytes == 111);
 
+        assert_se(parse_size("111.4", 1024, &bytes) == 0);
+        assert_se(bytes == 111);
+
         assert_se(parse_size(" 112 B", 1024, &bytes) == 0);
         assert_se(bytes == 112);
 
-        assert_se(parse_size("3 K", 1024, &bytes) == 0);
+        assert_se(parse_size(" 112.6 B", 1024, &bytes) == 0);
+        assert_se(bytes == 112);
+
+        assert_se(parse_size("3.5 K", 1024, &bytes) == 0);
+        assert_se(bytes == 3*1024 + 512);
+
+        assert_se(parse_size("3. K", 1024, &bytes) == 0);
+        assert_se(bytes == 3*1024);
+
+        assert_se(parse_size("3.0 K", 1024, &bytes) == 0);
         assert_se(bytes == 3*1024);
 
-        assert_se(parse_size(" 4 M 11K", 1024, &bytes) == 0);
-        assert_se(bytes == 4*1024*1024 + 11 * 1024);
+        assert_se(parse_size("3. 0 K", 1024, &bytes) == 0);
+        assert_se(bytes == 3);
 
-        assert_se(parse_size("3B3G", 1024, &bytes) == 0);
-        assert_se(bytes == 3ULL*1024*1024*1024 + 3);
+        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(bytes == 3ULL*1024*1024*1024 + 512*1024*1024 + 3);
 
         assert_se(parse_size("3B3G4T", 1024, &bytes) == 0);
         assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3);
@@ -464,6 +480,10 @@ static void test_parse_size(void) {
 
         assert_se(parse_size("12X", 1024, &bytes) == -EINVAL);
 
+        assert_se(parse_size("12.5X", 1024, &bytes) == -EINVAL);
+
+        assert_se(parse_size("12.5e3", 1024, &bytes) == -EINVAL);
+
         assert_se(parse_size("1024E", 1024, &bytes) == -ERANGE);
         assert_se(parse_size("-1", 1024, &bytes) == -ERANGE);
         assert_se(parse_size("-1024E", 1024, &bytes) == -ERANGE);
@@ -473,6 +493,14 @@ static void test_parse_size(void) {
         assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
 }
 
+static void test_config_parse_iec_off(void) {
+        off_t offset = 0;
+        assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
+        assert_se(offset == 4 * 1024 * 1024);
+
+        assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
+}
+
 static void test_strextend(void) {
         _cleanup_free_ char *str = strdup("0123");
         strextend(&str, "456", "78", "9", NULL);
@@ -589,6 +617,9 @@ static void test_writing_tmpfile(void) {
 }
 
 int main(int argc, char *argv[]) {
+        log_parse_environment();
+        log_open();
+
         test_streq_ptr();
         test_first_word();
         test_close_many();
@@ -618,6 +649,7 @@ int main(int argc, char *argv[]) {
         test_get_process_comm();
         test_protect_errno();
         test_parse_size();
+        test_config_parse_iec_off();
         test_strextend();
         test_strrep();
         test_split_pair();



More information about the systemd-commits mailing list