lib: add sys_io_ranges_overlap()
authorRalph Boehme <slow@samba.org>
Sat, 26 Jun 2021 10:21:19 +0000 (12:21 +0200)
committerJule Anger <janger@samba.org>
Wed, 11 Aug 2021 09:54:14 +0000 (09:54 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12033

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 4f1a02909b8694dcc30fd5c7c6772fcfa1092ed9)

lib/util/sys_rw.c
lib/util/sys_rw.h
lib/util/tests/test_sys_rw.c [new file with mode: 0644]
lib/util/wscript_build
selftest/tests.py

index d74395fc409143fbc5a2cc3e2d0bb4e6a1100d3f..02aaa871a3991fb684454302223187a81ef8f1f4 100644 (file)
@@ -48,6 +48,31 @@ bool sys_valid_io_range(off_t offset, size_t length)
        return true;
 }
 
+bool sys_io_ranges_overlap(size_t c1, off_t o1,
+                          size_t c2, off_t o2)
+{
+       if (c1 == 0 || c2 == 0) {
+               return false;
+       }
+       if (o2 < o1) {
+               /*
+                *          o1
+                *          |····c1····|
+                *  o2
+                *  |····c2···| ?
+                */
+               return (o2 + c2 > o1);
+       } else {
+               /*
+                *  o1
+                *  |····c1···|
+                *          o2
+                *          |····c2····| ?
+                */
+               return (o1 + c1 > o2);
+       }
+}
+
 /*******************************************************************
 A read wrapper that will deal with EINTR/EWOULDBLOCK
 ********************************************************************/
index b224ecb30ac7ca949f61fbc80c0d42db5264eace..6693d34de57273151775b05d57df19d77d0e8156 100644 (file)
@@ -28,6 +28,8 @@
 struct iovec;
 
 bool sys_valid_io_range(off_t offset, size_t length);
+bool sys_io_ranges_overlap(size_t c1, off_t o1,
+                          size_t c2, off_t o2);
 ssize_t sys_read(int fd, void *buf, size_t count);
 void sys_read_v(int fd, void *buf, size_t count);
 ssize_t sys_write(int fd, const void *buf, size_t count);
diff --git a/lib/util/tests/test_sys_rw.c b/lib/util/tests/test_sys_rw.c
new file mode 100644 (file)
index 0000000..551a6a0
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *
+ *  Unit test for sys_rw.c
+ *
+ *  Copyright (C) Ralph Böhme 2021
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "lib/replace/replace.h"
+#include "system/dir.h"
+
+#include "lib/util/sys_rw.c"
+
+static void test_sys_io_ranges_overlap(void **state)
+{
+       bool overlap;
+
+       /*
+        * sys_io_ranges_overlap() args are:
+        *
+        * src size, src offset, dst size, dst offset
+        */
+
+       /* src and dst size 0 => no overlap */
+       overlap = sys_io_ranges_overlap(0, 0, 0, 0);
+       assert_false(overlap);
+
+       /* dst size 0 => no overlap */
+       overlap = sys_io_ranges_overlap(1, 0, 0, 0);
+       assert_false(overlap);
+
+       /* src size 0 => no overlap */
+       overlap = sys_io_ranges_overlap(0, 0, 1, 0);
+       assert_false(overlap);
+
+       /* same range => overlap */
+       overlap = sys_io_ranges_overlap(1, 0, 1, 0);
+       assert_true(overlap);
+
+       /*
+        * |.|
+        *   |.|
+        * src before dst => no overlap
+        */
+       overlap = sys_io_ranges_overlap(1, 0, 1, 1);
+       assert_false(overlap);
+
+       /*
+        * |..|
+        *  |..|
+        * src into dst => overlap
+        */
+       overlap = sys_io_ranges_overlap(2, 0, 2, 1);
+       assert_true(overlap);
+
+       /*
+        * |....|
+        *  |..|
+        * src encompasses dst => overlap
+        */
+       overlap = sys_io_ranges_overlap(4, 0, 1, 2);
+       assert_true(overlap);
+
+
+       /*
+        *  |..|
+        * |..|
+        * dst into src => overlap
+        */
+       overlap = sys_io_ranges_overlap(2, 1, 2, 0);
+       assert_true(overlap);
+
+       /*
+        *  |..|
+        * |....|
+        * dst encompasses src => overlap
+        */
+       overlap = sys_io_ranges_overlap(2, 1, 4, 0);
+       assert_true(overlap);
+}
+
+int main(int argc, char **argv)
+{
+       const struct CMUnitTest tests[] = {
+               cmocka_unit_test(test_sys_io_ranges_overlap),
+       };
+
+       cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+
+       return cmocka_run_group_tests(tests, NULL, NULL);
+}
index 460661e9a634e7362bda1627fd0da85084cc3520..839d3c2e2e90a2c55d7f8adf70fa83febc799817 100644 (file)
@@ -356,3 +356,9 @@ else:
                      deps='cmocka replace talloc samba-util',
                      local_include=False,
                      for_selftest=True)
+
+    bld.SAMBA_BINARY('test_sys_rw',
+                     source='tests/test_sys_rw.c',
+                     deps='cmocka replace samba-util',
+                     local_include=False,
+                     for_selftest=True)
index 6bf46ae5621ed798742b385c5b62b2e654115f19..3645904801ac0e3ad62cb056b18e8fe759f85a01 100644 (file)
@@ -407,6 +407,8 @@ plantestsuite("samba.unittests.util", "none",
               [os.path.join(bindir(), "default/lib/util/test_util")])
 plantestsuite("samba.unittests.memcache", "none",
               [os.path.join(bindir(), "default/lib/util/test_memcache")])
+plantestsuite("samba.unittests.sys_rw", "none",
+              [os.path.join(bindir(), "default/lib/util/test_sys_rw")])
 plantestsuite("samba.unittests.ntlm_check", "none",
               [os.path.join(bindir(), "default/libcli/auth/test_ntlm_check")])
 plantestsuite("samba.unittests.gnutls", "none",