]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/test/test-parse-util.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / test / test-parse-util.c
index d3ae0599ab45a610845aa435f4a7f9f92f70c2a9..8259e133c3320392692c04e2d7337f1e0974c5c8 100644 (file)
@@ -1,5 +1,4 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
 #include <locale.h>
 #include <math.h>
 
+#include "alloc-util.h"
+#include "errno-list.h"
 #include "log.h"
 #include "parse-util.h"
+#include "string-util.h"
 
 static void test_parse_boolean(void) {
         assert_se(parse_boolean("1") == 1);
@@ -81,6 +83,9 @@ static void test_parse_pid(void) {
 
         r = parse_pid("junk", &pid);
         assert_se(r == -EINVAL);
+
+        r = parse_pid("", &pid);
+        assert_se(r == -EINVAL);
 }
 
 static void test_parse_mode(void) {
@@ -100,6 +105,8 @@ static void test_parse_mode(void) {
 static void test_parse_size(void) {
         uint64_t bytes;
 
+        assert_se(parse_size("", 1024, &bytes) == -EINVAL);
+
         assert_se(parse_size("111", 1024, &bytes) == 0);
         assert_se(bytes == 111);
 
@@ -259,6 +266,10 @@ static void test_parse_range(void) {
         assert_se(lower == 9999);
         assert_se(upper == 9999);
 
+        assert_se(parse_range("-123", &lower, &upper) == -EINVAL);
+        assert_se(lower == 9999);
+        assert_se(upper == 9999);
+
         assert_se(parse_range("-111-123", &lower, &upper) == -EINVAL);
         assert_se(lower == 9999);
         assert_se(upper == 9999);
@@ -352,8 +363,35 @@ static void test_safe_atolli(void) {
         assert_se(r == 0);
         assert_se(l == 12345);
 
+        r = safe_atolli("  12345", &l);
+        assert_se(r == 0);
+        assert_se(l == 12345);
+
+        r = safe_atolli("-12345", &l);
+        assert_se(r == 0);
+        assert_se(l == -12345);
+
+        r = safe_atolli("  -12345", &l);
+        assert_se(r == 0);
+        assert_se(l == -12345);
+
+        r = safe_atolli("12345678901234567890", &l);
+        assert_se(r == -ERANGE);
+
+        r = safe_atolli("-12345678901234567890", &l);
+        assert_se(r == -ERANGE);
+
         r = safe_atolli("junk", &l);
         assert_se(r == -EINVAL);
+
+        r = safe_atolli("123x", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atolli("12.3", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atolli("", &l);
+        assert_se(r == -EINVAL);
 }
 
 static void test_safe_atou16(void) {
@@ -364,11 +402,30 @@ static void test_safe_atou16(void) {
         assert_se(r == 0);
         assert_se(l == 12345);
 
+        r = safe_atou16("  12345", &l);
+        assert_se(r == 0);
+        assert_se(l == 12345);
+
         r = safe_atou16("123456", &l);
         assert_se(r == -ERANGE);
 
+        r = safe_atou16("-1", &l);
+        assert_se(r == -ERANGE);
+
+        r = safe_atou16("  -1", &l);
+        assert_se(r == -ERANGE);
+
         r = safe_atou16("junk", &l);
         assert_se(r == -EINVAL);
+
+        r = safe_atou16("123x", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atou16("12.3", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atou16("", &l);
+        assert_se(r == -EINVAL);
 }
 
 static void test_safe_atoi16(void) {
@@ -379,11 +436,108 @@ static void test_safe_atoi16(void) {
         assert_se(r == 0);
         assert_se(l == -12345);
 
+        r = safe_atoi16("  -12345", &l);
+        assert_se(r == 0);
+        assert_se(l == -12345);
+
+        r = safe_atoi16("32767", &l);
+        assert_se(r == 0);
+        assert_se(l == 32767);
+
+        r = safe_atoi16("  32767", &l);
+        assert_se(r == 0);
+        assert_se(l == 32767);
+
         r = safe_atoi16("36536", &l);
         assert_se(r == -ERANGE);
 
+        r = safe_atoi16("-32769", &l);
+        assert_se(r == -ERANGE);
+
         r = safe_atoi16("junk", &l);
         assert_se(r == -EINVAL);
+
+        r = safe_atoi16("123x", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atoi16("12.3", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atoi16("", &l);
+        assert_se(r == -EINVAL);
+}
+
+static void test_safe_atou64(void) {
+        int r;
+        uint64_t l;
+
+        r = safe_atou64("12345", &l);
+        assert_se(r == 0);
+        assert_se(l == 12345);
+
+        r = safe_atou64("  12345", &l);
+        assert_se(r == 0);
+        assert_se(l == 12345);
+
+        r = safe_atou64("18446744073709551617", &l);
+        assert_se(r == -ERANGE);
+
+        r = safe_atou64("-1", &l);
+        assert_se(r == -ERANGE);
+
+        r = safe_atou64("  -1", &l);
+        assert_se(r == -ERANGE);
+
+        r = safe_atou64("junk", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atou64("123x", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atou64("12.3", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atou64("", &l);
+        assert_se(r == -EINVAL);
+}
+
+static void test_safe_atoi64(void) {
+        int r;
+        int64_t l;
+
+        r = safe_atoi64("-12345", &l);
+        assert_se(r == 0);
+        assert_se(l == -12345);
+
+        r = safe_atoi64("  -12345", &l);
+        assert_se(r == 0);
+        assert_se(l == -12345);
+
+        r = safe_atoi64("32767", &l);
+        assert_se(r == 0);
+        assert_se(l == 32767);
+
+        r = safe_atoi64("  32767", &l);
+        assert_se(r == 0);
+        assert_se(l == 32767);
+
+        r = safe_atoi64("9223372036854775813", &l);
+        assert_se(r == -ERANGE);
+
+        r = safe_atoi64("-9223372036854775813", &l);
+        assert_se(r == -ERANGE);
+
+        r = safe_atoi64("junk", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atoi64("123x", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atoi64("12.3", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atoi64("", &l);
+        assert_se(r == -EINVAL);
 }
 
 static void test_safe_atod(void) {
@@ -405,6 +559,9 @@ static void test_safe_atod(void) {
         strtod("0,5", &e);
         assert_se(*e == ',');
 
+        r = safe_atod("", &d);
+        assert_se(r == -EINVAL);
+
         /* Check if this really is locale independent */
         if (setlocale(LC_NUMERIC, "de_DE.utf8")) {
 
@@ -417,6 +574,9 @@ static void test_safe_atod(void) {
 
                 errno = 0;
                 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
+
+                r = safe_atod("", &d);
+                assert_se(r == -EINVAL);
         }
 
         /* And check again, reset */
@@ -432,6 +592,144 @@ static void test_safe_atod(void) {
         errno = 0;
         strtod("0,5", &e);
         assert_se(*e == ',');
+
+        r = safe_atod("", &d);
+        assert_se(r == -EINVAL);
+}
+
+static void test_parse_percent(void) {
+        assert_se(parse_percent("") == -EINVAL);
+        assert_se(parse_percent("foo") == -EINVAL);
+        assert_se(parse_percent("0") == -EINVAL);
+        assert_se(parse_percent("50") == -EINVAL);
+        assert_se(parse_percent("100") == -EINVAL);
+        assert_se(parse_percent("-1") == -EINVAL);
+        assert_se(parse_percent("0%") == 0);
+        assert_se(parse_percent("55%") == 55);
+        assert_se(parse_percent("100%") == 100);
+        assert_se(parse_percent("-7%") == -ERANGE);
+        assert_se(parse_percent("107%") == -ERANGE);
+        assert_se(parse_percent("%") == -EINVAL);
+        assert_se(parse_percent("%%") == -EINVAL);
+        assert_se(parse_percent("%1") == -EINVAL);
+        assert_se(parse_percent("1%%") == -EINVAL);
+        assert_se(parse_percent("3.2%") == -EINVAL);
+}
+
+static void test_parse_percent_unbounded(void) {
+        assert_se(parse_percent_unbounded("101%") == 101);
+        assert_se(parse_percent_unbounded("400%") == 400);
+}
+
+static void test_parse_nice(void) {
+        int n;
+
+        assert_se(parse_nice("0", &n) >= 0 && n == 0);
+        assert_se(parse_nice("+0", &n) >= 0 && n == 0);
+        assert_se(parse_nice("-1", &n) >= 0 && n == -1);
+        assert_se(parse_nice("-2", &n) >= 0 && n == -2);
+        assert_se(parse_nice("1", &n) >= 0 && n == 1);
+        assert_se(parse_nice("2", &n) >= 0 && n == 2);
+        assert_se(parse_nice("+1", &n) >= 0 && n == 1);
+        assert_se(parse_nice("+2", &n) >= 0 && n == 2);
+        assert_se(parse_nice("-20", &n) >= 0 && n == -20);
+        assert_se(parse_nice("19", &n) >= 0 && n == 19);
+        assert_se(parse_nice("+19", &n) >= 0 && n == 19);
+
+
+        assert_se(parse_nice("", &n) == -EINVAL);
+        assert_se(parse_nice("-", &n) == -EINVAL);
+        assert_se(parse_nice("+", &n) == -EINVAL);
+        assert_se(parse_nice("xx", &n) == -EINVAL);
+        assert_se(parse_nice("-50", &n) == -ERANGE);
+        assert_se(parse_nice("50", &n) == -ERANGE);
+        assert_se(parse_nice("+50", &n) == -ERANGE);
+        assert_se(parse_nice("-21", &n) == -ERANGE);
+        assert_se(parse_nice("20", &n) == -ERANGE);
+        assert_se(parse_nice("+20", &n) == -ERANGE);
+}
+
+static void test_parse_dev(void) {
+        dev_t dev;
+
+        assert_se(parse_dev("", &dev) == -EINVAL);
+        assert_se(parse_dev("junk", &dev) == -EINVAL);
+        assert_se(parse_dev("0", &dev) == -EINVAL);
+        assert_se(parse_dev("5", &dev) == -EINVAL);
+        assert_se(parse_dev("5:", &dev) == -EINVAL);
+        assert_se(parse_dev(":5", &dev) == -EINVAL);
+#if SIZEOF_DEV_T < 8
+        assert_se(parse_dev("4294967295:4294967295", &dev) == -EINVAL);
+#endif
+        assert_se(parse_dev("8:11", &dev) >= 0 && major(dev) == 8 && minor(dev) == 11);
+}
+
+static void test_parse_errno(void) {
+        assert_se(parse_errno("EILSEQ") == EILSEQ);
+        assert_se(parse_errno("EINVAL") == EINVAL);
+        assert_se(parse_errno("0") == 0);
+        assert_se(parse_errno("1") == 1);
+        assert_se(parse_errno("4095") == 4095);
+
+        assert_se(parse_errno("-1") == -ERANGE);
+        assert_se(parse_errno("-3") == -ERANGE);
+        assert_se(parse_errno("4096") == -ERANGE);
+
+        assert_se(parse_errno("") == -EINVAL);
+        assert_se(parse_errno("12.3") == -EINVAL);
+        assert_se(parse_errno("123junk") == -EINVAL);
+        assert_se(parse_errno("junk123") == -EINVAL);
+        assert_se(parse_errno("255EILSEQ") == -EINVAL);
+        assert_se(parse_errno("EINVAL12") == -EINVAL);
+        assert_se(parse_errno("-EINVAL") == -EINVAL);
+        assert_se(parse_errno("EINVALaaa") == -EINVAL);
+}
+
+static void test_parse_syscall_and_errno(void) {
+        _cleanup_free_ char *n = NULL;
+        int e;
+
+        assert_se(parse_syscall_and_errno("uname:EILSEQ", &n, &e) >= 0);
+        assert_se(streq(n, "uname"));
+        assert_se(e == errno_from_name("EILSEQ") && e >= 0);
+        n = mfree(n);
+
+        assert_se(parse_syscall_and_errno("uname:EINVAL", &n, &e) >= 0);
+        assert_se(streq(n, "uname"));
+        assert_se(e == errno_from_name("EINVAL") && e >= 0);
+        n = mfree(n);
+
+        assert_se(parse_syscall_and_errno("@sync:4095", &n, &e) >= 0);
+        assert_se(streq(n, "@sync"));
+        assert_se(e == 4095);
+        n = mfree(n);
+
+        /* If errno is omitted, then e is set to -1 */
+        assert_se(parse_syscall_and_errno("mount", &n, &e) >= 0);
+        assert_se(streq(n, "mount"));
+        assert_se(e == -1);
+        n = mfree(n);
+
+        /* parse_syscall_and_errno() does not check the syscall name is valid or not. */
+        assert_se(parse_syscall_and_errno("hoge:255", &n, &e) >= 0);
+        assert_se(streq(n, "hoge"));
+        assert_se(e == 255);
+        n = mfree(n);
+
+        /* The function checks the syscall name is empty or not. */
+        assert_se(parse_syscall_and_errno("", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno(":255", &n, &e) == -EINVAL);
+
+        /* errno must be a valid errno name or number between 0 and ERRNO_MAX == 4095 */
+        assert_se(parse_syscall_and_errno("hoge:4096", &n, &e) == -ERANGE);
+        assert_se(parse_syscall_and_errno("hoge:-3", &n, &e) == -ERANGE);
+        assert_se(parse_syscall_and_errno("hoge:12.3", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno("hoge:123junk", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno("hoge:junk123", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno("hoge:255:EILSEQ", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno("hoge:-EINVAL", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno("hoge:EINVALaaa", &n, &e) == -EINVAL);
+        assert_se(parse_syscall_and_errno("hoge:", &n, &e) == -EINVAL);
 }
 
 int main(int argc, char *argv[]) {
@@ -446,7 +744,15 @@ int main(int argc, char *argv[]) {
         test_safe_atolli();
         test_safe_atou16();
         test_safe_atoi16();
+        test_safe_atou64();
+        test_safe_atoi64();
         test_safe_atod();
+        test_parse_percent();
+        test_parse_percent_unbounded();
+        test_parse_nice();
+        test_parse_dev();
+        test_parse_errno();
+        test_parse_syscall_and_errno();
 
         return 0;
 }