chiark / gitweb /
tree-wide: drop copyright headers from frequent contributors
[elogind.git] / src / test / test-parse-util.c
index 0175f3c19a72becab7c7346a09e8108193217292..73688952f005e733b4468fe6b41d22d906dd4357 100644 (file)
@@ -1,28 +1,15 @@
-/***
-  This file is part of systemd.
-
-  Copyright 2010 Lennart Poettering
-  Copyright 2013 Thomas H.P. Andersen
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
+#include <errno.h>
 #include <locale.h>
 #include <math.h>
+//#include <sys/socket.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);
@@ -79,6 +66,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) {
@@ -98,6 +88,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);
 
@@ -258,6 +250,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);
@@ -372,6 +368,15 @@ static void test_safe_atolli(void) {
 
         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) {
@@ -400,6 +405,12 @@ static void test_safe_atou16(void) {
 
         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) {
@@ -433,6 +444,50 @@ static void test_safe_atoi16(void) {
 
         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_atoux16(void) {
+        int r;
+        uint16_t l;
+
+        r = safe_atoux16("1234", &l);
+        assert_se(r == 0);
+        assert_se(l == 0x1234);
+
+        r = safe_atoux16("abcd", &l);
+        assert_se(r == 0);
+        assert_se(l == 0xabcd);
+
+        r = safe_atoux16("  1234", &l);
+        assert_se(r == 0);
+        assert_se(l == 0x1234);
+
+        r = safe_atoux16("12345", &l);
+        assert_se(r == -ERANGE);
+
+        r = safe_atoux16("-1", &l);
+        assert_se(r == -ERANGE);
+
+        r = safe_atoux16("  -1", &l);
+        assert_se(r == -ERANGE);
+
+        r = safe_atoux16("junk", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atoux16("123x", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atoux16("12.3", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atoux16("", &l);
+        assert_se(r == -EINVAL);
 }
 
 static void test_safe_atou64(void) {
@@ -461,6 +516,12 @@ static void test_safe_atou64(void) {
 
         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) {
@@ -494,6 +555,12 @@ static void test_safe_atoi64(void) {
 
         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) {
@@ -515,6 +582,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")) {
 
@@ -526,7 +596,13 @@ static void test_safe_atod(void) {
                 assert_se(r == -EINVAL);
 
                 errno = 0;
+/// elogind supports musl_libc, and their strtod doesn't seem to use the set locale.
+#if defined(__GLIBC__)
                 assert_se(fabs(strtod("0,5", &e) - 0.5) < 0.00001);
+#endif // __GLIBC__
+
+                r = safe_atod("", &d);
+                assert_se(r == -EINVAL);
         }
 
         /* And check again, reset */
@@ -542,6 +618,9 @@ 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) {
@@ -560,6 +639,7 @@ static void test_parse_percent(void) {
         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) {
@@ -567,6 +647,54 @@ static void test_parse_percent_unbounded(void) {
         assert_se(parse_percent_unbounded("400%") == 400);
 }
 
+static void test_parse_permille(void) {
+        assert_se(parse_permille("") == -EINVAL);
+        assert_se(parse_permille("foo") == -EINVAL);
+        assert_se(parse_permille("0") == -EINVAL);
+        assert_se(parse_permille("50") == -EINVAL);
+        assert_se(parse_permille("100") == -EINVAL);
+        assert_se(parse_permille("-1") == -EINVAL);
+
+        assert_se(parse_permille("0‰") == 0);
+        assert_se(parse_permille("555‰") == 555);
+        assert_se(parse_permille("1000‰") == 1000);
+        assert_se(parse_permille("-7‰") == -ERANGE);
+        assert_se(parse_permille("1007‰") == -ERANGE);
+        assert_se(parse_permille("‰") == -EINVAL);
+        assert_se(parse_permille("‰‰") == -EINVAL);
+        assert_se(parse_permille("‰1") == -EINVAL);
+        assert_se(parse_permille("1‰‰") == -EINVAL);
+        assert_se(parse_permille("3.2‰") == -EINVAL);
+
+        assert_se(parse_permille("0%") == 0);
+        assert_se(parse_permille("55%") == 550);
+        assert_se(parse_permille("55.5%") == 555);
+        assert_se(parse_permille("100%") == 1000);
+        assert_se(parse_permille("-7%") == -ERANGE);
+        assert_se(parse_permille("107%") == -ERANGE);
+        assert_se(parse_permille("%") == -EINVAL);
+        assert_se(parse_permille("%%") == -EINVAL);
+        assert_se(parse_permille("%1") == -EINVAL);
+        assert_se(parse_permille("1%%") == -EINVAL);
+        assert_se(parse_permille("3.21%") == -EINVAL);
+}
+
+static void test_parse_permille_unbounded(void) {
+        assert_se(parse_permille_unbounded("1001‰") == 1001);
+        assert_se(parse_permille_unbounded("4000‰") == 4000);
+        assert_se(parse_permille_unbounded("2147483647‰") == 2147483647);
+        assert_se(parse_permille_unbounded("2147483648‰") == -ERANGE);
+        assert_se(parse_permille_unbounded("4294967295‰") == -ERANGE);
+        assert_se(parse_permille_unbounded("4294967296‰") == -ERANGE);
+
+        assert_se(parse_permille_unbounded("101%") == 1010);
+        assert_se(parse_permille_unbounded("400%") == 4000);
+        assert_se(parse_permille_unbounded("214748364.7%") == 2147483647);
+        assert_se(parse_permille_unbounded("214748364.8%") == -ERANGE);
+        assert_se(parse_permille_unbounded("429496729.5%") == -ERANGE);
+        assert_se(parse_permille_unbounded("429496729.6%") == -ERANGE);
+}
+
 #if 0 /// UNNEEDED by elogind
 static void test_parse_nice(void) {
         int n;
@@ -583,7 +711,6 @@ static void test_parse_nice(void) {
         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);
@@ -600,6 +727,8 @@ static void test_parse_nice(void) {
 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);
@@ -610,6 +739,95 @@ static void test_parse_dev(void) {
         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);
+}
+
+static void test_parse_mtu(void) {
+        uint32_t mtu = 0;
+
+        assert_se(parse_mtu(AF_UNSPEC, "1500", &mtu) >= 0 && mtu == 1500);
+        assert_se(parse_mtu(AF_UNSPEC, "1400", &mtu) >= 0 && mtu == 1400);
+        assert_se(parse_mtu(AF_UNSPEC, "65535", &mtu) >= 0 && mtu == 65535);
+        assert_se(parse_mtu(AF_UNSPEC, "65536", &mtu) >= 0 && mtu == 65536);
+        assert_se(parse_mtu(AF_UNSPEC, "4294967295", &mtu) >= 0 && mtu == 4294967295);
+        assert_se(parse_mtu(AF_UNSPEC, "500", &mtu) >= 0 && mtu == 500);
+        assert_se(parse_mtu(AF_UNSPEC, "1280", &mtu) >= 0 && mtu == 1280);
+        assert_se(parse_mtu(AF_INET6, "1280", &mtu) >= 0 && mtu == 1280);
+        assert_se(parse_mtu(AF_INET6, "1279", &mtu) == -ERANGE);
+        assert_se(parse_mtu(AF_UNSPEC, "4294967296", &mtu) == -ERANGE);
+        assert_se(parse_mtu(AF_INET6, "4294967296", &mtu) == -ERANGE);
+        assert_se(parse_mtu(AF_INET6, "68", &mtu) == -ERANGE);
+        assert_se(parse_mtu(AF_UNSPEC, "68", &mtu) >= 0 && mtu == 68);
+        assert_se(parse_mtu(AF_UNSPEC, "67", &mtu) == -ERANGE);
+        assert_se(parse_mtu(AF_UNSPEC, "0", &mtu) == -ERANGE);
+        assert_se(parse_mtu(AF_UNSPEC, "", &mtu) == -EINVAL);
+}
+
 int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
@@ -624,15 +842,21 @@ int main(int argc, char *argv[]) {
         test_safe_atolli();
         test_safe_atou16();
         test_safe_atoi16();
+        test_safe_atoux16();
         test_safe_atou64();
         test_safe_atoi64();
         test_safe_atod();
         test_parse_percent();
         test_parse_percent_unbounded();
+        test_parse_permille();
+        test_parse_permille_unbounded();
 #if 0 /// UNNEEDED by elogind
         test_parse_nice();
 #endif // 0
         test_parse_dev();
+        test_parse_errno();
+        test_parse_syscall_and_errno();
+        test_parse_mtu();
 
         return 0;
 }