[PATCH] Fix byteorder.h and introduce bytearray.h

Andreas Schneider asn at samba.org
Thu Dec 20 13:02:16 UTC 2018


Hello,

the macros in byteorder.h undefined behavior issues.

Example:
    source3/libsmb/clientgen.c:42:2: runtime error: left shift of 38400 by
    16 places cannot be represented in type 'int'

I always find the naming of those macros very confusing. I never really know 
what they are doing by the name I need to look at the code.

For libssh I wrote a bytearray.h some weeks ago, it does correct casting all 
the time so we don't run into undefined behavior. I used naming I known from 
Samba's NDR. I would like to introduce that in Samba and encourage using those 
macros in future. Here is an example:

uint32_t i = PULL_LE_U32(buf, 0)

I think pull and u32 are obvious and LE is little endian order. There are 
macros for pushing too and also for big endian.

I've copied over the cmocka test I wrote to ensure the macros are working 
correctly.

So in future we should replace *VAL* macros with the new once to remove 
byteorder.h one day if possible.


Comments are welcome.


CI: https://gitlab.com/samba-team/devel/samba/pipelines/40845684


Thanks,


	Andreas


-- 
Andreas Schneider                      asn at samba.org
Samba Team                             www.samba.org
GPG-ID:     8DFF53E18F2ABC8D8F3C92237EE0FC4DCC014E3D
-------------- next part --------------
>From 643de5a8f6f6891b3d65e4a0b31b8b177053746c Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 20 Dec 2018 08:37:32 +0100
Subject: [PATCH 1/7] lib:util: Add bytearray.h

This is an implementation which doesn't have undefined behavior
problems. It casts correctly that calculations are don in the correct
integer space. Also the naming is less confusing than what we have in
byteorder.h.

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/util/bytearray.h            |  92 +++++++
 lib/util/tests/test_bytearray.c | 434 ++++++++++++++++++++++++++++++++
 lib/util/wscript_build          |   8 +-
 selftest/tests.py               |   2 +
 4 files changed, 535 insertions(+), 1 deletion(-)
 create mode 100644 lib/util/bytearray.h
 create mode 100644 lib/util/tests/test_bytearray.c

diff --git a/lib/util/bytearray.h b/lib/util/bytearray.h
new file mode 100644
index 00000000000..b48d9c1dc45
--- /dev/null
+++ b/lib/util/bytearray.h
@@ -0,0 +1,92 @@
+/*
+ * Macros for handling integer types in byte arrays
+ *
+ * This file is originally from the libssh.org project
+ *
+ * Copyright (c) 2018 Andreas Schneider <asn at cryptomilk.org>
+ *
+ * This library 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.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef _BYTEARRAY_H
+#define _BYTEARRAY_H
+
+#define _DATA_BYTE_CONST(data, pos) \
+    ((uint8_t)(((const uint8_t *)(data))[(pos)]))
+
+#define _DATA_BYTE(data, pos) \
+    (((uint8_t *)(data))[(pos)])
+
+/*
+ * These macros pull or push integer values from byte arrays stored in
+ * little-endian byte order.
+ */
+#define PULL_LE_U8(data, pos) \
+    (_DATA_BYTE_CONST(data, pos))
+
+#define PULL_LE_U16(data, pos) \
+    ((uint16_t)PULL_LE_U8(data, pos) | ((uint16_t)(PULL_LE_U8(data, (pos) + 1))) << 8)
+
+#define PULL_LE_U32(data, pos) \
+    ((uint32_t)(PULL_LE_U16(data, pos) | ((uint32_t)PULL_LE_U16(data, (pos) + 2)) << 16))
+
+#define PULL_LE_U64(data, pos) \
+    ((uint64_t)(PULL_LE_U32(data, pos) | ((uint64_t)PULL_LE_U32(data, (pos) + 4)) << 32))
+
+
+#define PUSH_LE_U8(data, pos, val) \
+    (_DATA_BYTE(data, pos) = ((uint8_t)(val)))
+
+#define PUSH_LE_U16(data, pos, val) \
+    (PUSH_LE_U8((data), (pos), (uint8_t)((uint16_t)(val) & 0xff)), PUSH_LE_U8((data), (pos) + 1, (uint8_t)((uint16_t)(val) >> 8)))
+
+#define PUSH_LE_U32(data, pos, val) \
+    (PUSH_LE_U16((data), (pos), (uint16_t)((uint32_t)(val) & 0xffff)), PUSH_LE_U16((data), (pos) + 2, (uint16_t)((uint32_t)(val) >> 16)))
+
+#define PUSH_LE_U64(data, pos, val) \
+    (PUSH_LE_U32((data), (pos), (uint32_t)((uint64_t)(val) & 0xffffffff)), PUSH_LE_U32((data), (pos) + 4, (uint32_t)((uint64_t)(val) >> 32)))
+
+
+
+/*
+ * These macros pull or push integer values from byte arrays stored in
+ * big-endian byte order (network byte order).
+ */
+#define PULL_BE_U8(data, pos) \
+    (_DATA_BYTE_CONST(data, pos))
+
+#define PULL_BE_U16(data, pos) \
+    ((((uint16_t)(PULL_BE_U8(data, pos))) << 8) | (uint16_t)PULL_BE_U8(data, (pos) + 1))
+
+#define PULL_BE_U32(data, pos) \
+    ((((uint32_t)PULL_BE_U16(data, pos)) << 16) | (uint32_t)(PULL_BE_U16(data, (pos) + 2)))
+
+#define PULL_BE_U64(data, pos) \
+    ((((uint64_t)PULL_BE_U32(data, pos)) << 32) | (uint64_t)(PULL_BE_U32(data, (pos) + 4)))
+
+
+
+#define PUSH_BE_U8(data, pos, val) \
+    (_DATA_BYTE(data, pos) = ((uint8_t)(val)))
+
+#define PUSH_BE_U16(data, pos, val) \
+    (PUSH_BE_U8((data), (pos), (uint8_t)(((uint16_t)(val)) >> 8)), PUSH_BE_U8((data), (pos) + 1, (uint8_t)((val) & 0xff)))
+
+#define PUSH_BE_U32(data, pos, val) \
+    (PUSH_BE_U16((data), (pos), (uint16_t)(((uint32_t)(val)) >> 16)), PUSH_BE_U16((data), (pos) + 2, (uint16_t)((val) & 0xffff)))
+
+#define PUSH_BE_U64(data, pos, val) \
+    (PUSH_BE_U32((data), (pos), (uint32_t)(((uint64_t)(val)) >> 32)), PUSH_BE_U32((data), (pos) + 4, (uint32_t)((val) & 0xffffffff)))
+
+#endif /* _BYTEARRAY_H */
diff --git a/lib/util/tests/test_bytearray.c b/lib/util/tests/test_bytearray.c
new file mode 100644
index 00000000000..8834b2119b1
--- /dev/null
+++ b/lib/util/tests/test_bytearray.c
@@ -0,0 +1,434 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) 2018      Andreas Schneider <asn at samba.org>
+ *
+ * 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 <setjmp.h>
+#include <cmocka.h>
+
+#include "lib/replace/replace.h"
+#include "lib/util/bytearray.h"
+
+static void torture_pull_le_u8(void **state)
+{
+	uint8_t data[2] = {0};
+	uint8_t result;
+
+	(void)state;
+
+	result = PULL_LE_U8(data, 0);
+	assert_int_equal(result, 0);
+
+	data[0] = 0x2a;
+	result = PULL_LE_U8(data, 0);
+	assert_int_equal(result, 42);
+
+
+	data[0] = 0xf;
+	result = PULL_LE_U8(data, 0);
+	assert_int_equal(result, 0xf);
+
+	data[0] = 0xff;
+	result = PULL_LE_U8(data, 0);
+	assert_int_equal(result, 0xff);
+
+	data[1] = 0x2a;
+	result = PULL_LE_U8(data, 1);
+	assert_int_equal(result, 42);
+}
+
+static void torture_pull_le_u16(void **state)
+{
+	uint8_t data[2] = {0, 0};
+	uint16_t result;
+
+	(void)state;
+
+	result = PULL_LE_U16(data, 0);
+	assert_int_equal(result, 0);
+
+	data[0] = 0x2a;
+	data[1] = 0x00;
+	result = PULL_LE_U16(data, 0);
+	assert_int_equal(result, 42);
+
+	data[0] = 0xff;
+	data[1] = 0x00;
+	result = PULL_LE_U16(data, 0);
+	assert_int_equal(result, 0x00ff);
+
+	data[0] = 0x00;
+	data[1] = 0xff;
+	result = PULL_LE_U16(data, 0);
+	assert_int_equal(result, 0xff00);
+
+	data[0] = 0xff;
+	data[1] = 0xff;
+	result = PULL_LE_U16(data, 0);
+	assert_int_equal(result, 0xffff);
+}
+
+static void torture_pull_le_u32(void **state)
+{
+	uint8_t data[4] = {0, 0, 0, 0};
+	uint32_t result;
+
+	(void)state;
+
+	result = PULL_LE_U32(data, 0);
+	assert_int_equal(result, 0);
+
+	data[0] = 0x2a;
+	data[1] = 0x00;
+	data[2] = 0x00;
+	data[3] = 0x00;
+	result = PULL_LE_U32(data, 0);
+	assert_int_equal(result, 42);
+
+	data[0] = 0xff;
+	data[1] = 0x00;
+	data[2] = 0x00;
+	data[3] = 0x00;
+	result = PULL_LE_U32(data, 0);
+	assert_int_equal(result, 0x00ff);
+
+	data[0] = 0x00;
+	data[1] = 0xff;
+	data[2] = 0x00;
+	data[3] = 0x00;
+	result = PULL_LE_U32(data, 0);
+	assert_int_equal(result, 0xff00);
+
+	data[0] = 0x00;
+	data[1] = 0x00;
+	data[2] = 0xff;
+	data[3] = 0x00;
+	result = PULL_LE_U32(data, 0);
+	assert_int_equal(result, 0xff0000);
+
+	data[0] = 0x00;
+	data[1] = 0x00;
+	data[2] = 0x00;
+	data[3] = 0xff;
+	result = PULL_LE_U32(data, 0);
+	assert_int_equal(result, 0xff000000);
+
+	data[0] = 0xff;
+	data[1] = 0xff;
+	data[2] = 0xff;
+	data[3] = 0xff;
+	result = PULL_LE_U32(data, 0);
+	assert_int_equal(result, 0xffffffff);
+}
+
+static void torture_push_le_u8(void **state)
+{
+	uint8_t data[4] = {0, 0, 0, 0};
+	uint8_t data2[4] = {42, 42, 42, 42};
+
+	(void)state;
+
+	PUSH_LE_U8(data, 0, 42);
+	PUSH_LE_U8(data, 1, 42);
+	PUSH_LE_U8(data, 2, 42);
+	PUSH_LE_U8(data, 3, 42);
+	assert_memory_equal(data, data2, sizeof(data));
+}
+
+static void torture_push_le_u16(void **state)
+{
+	uint8_t data[4] = {0, 0, 0, 0};
+	uint8_t data2[4] = {0xa6, 0x7f, 0x2a, 0x00};
+	uint16_t result;
+
+	(void)state;
+
+	PUSH_LE_U16(data, 0, 32678);
+	PUSH_LE_U16(data, 2, 42);
+	assert_memory_equal(data, data2, sizeof(data));
+
+	result = PULL_LE_U16(data, 2);
+	assert_int_equal(result, 42);
+
+	result = PULL_LE_U16(data, 0);
+	assert_int_equal(result, 32678);
+}
+
+static void torture_push_le_u32(void **state)
+{
+	uint8_t data[8] = {0};
+	uint8_t data2[8] = {0xa6, 0x7f, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00};
+	uint32_t result;
+
+	(void)state;
+
+	PUSH_LE_U32(data, 0, 32678);
+	PUSH_LE_U32(data, 4, 42);
+	assert_memory_equal(data, data2, sizeof(data));
+
+	result = PULL_LE_U32(data, 4);
+	assert_int_equal(result, 42);
+
+	result = PULL_LE_U32(data, 0);
+	assert_int_equal(result, 32678);
+
+	PUSH_LE_U32(data, 0, 0xfffefffe);
+	result = PULL_LE_U32(data, 0);
+	assert_int_equal(result, 0xfffefffe);
+}
+
+static void torture_push_le_u64(void **state)
+{
+	uint8_t data[16] = {0};
+	uint64_t result;
+
+	(void)state;
+
+	PUSH_LE_U64(data, 0, 32678);
+
+	result = PULL_LE_U64(data, 0);
+	assert_int_equal(result, 32678);
+
+	PUSH_LE_U64(data, 0, 0xfffefffefffefffeUL);
+
+	result = PULL_LE_U64(data, 0);
+	assert_int_equal(result, 0xfffefffefffefffeUL);
+}
+
+/****************** BIG ENDIAN ********************/
+
+static void torture_pull_be_u8(void **state)
+{
+	uint8_t data[2] = {0};
+	uint8_t result;
+
+	(void)state;
+
+	result = PULL_BE_U8(data, 0);
+	assert_int_equal(result, 0);
+
+	data[0] = 0x2a;
+	result = PULL_BE_U8(data, 0);
+	assert_int_equal(result, 42);
+
+
+	data[0] = 0xf;
+	result = PULL_BE_U8(data, 0);
+	assert_int_equal(result, 0xf);
+
+	data[0] = 0xff;
+	result = PULL_BE_U8(data, 0);
+	assert_int_equal(result, 0xff);
+
+	data[1] = 0x2a;
+	result = PULL_BE_U8(data, 1);
+	assert_int_equal(result, 42);
+}
+
+static void torture_pull_be_u16(void **state)
+{
+	uint8_t data[2] = {0, 0};
+	uint16_t result;
+
+	(void)state;
+
+	result = PULL_BE_U16(data, 0);
+	assert_int_equal(result, 0);
+
+	data[0] = 0x00;
+	data[1] = 0x2a;
+	result = PULL_BE_U16(data, 0);
+	assert_int_equal(result, 42);
+
+	data[0] = 0x00;
+	data[1] = 0xff;
+	result = PULL_BE_U16(data, 0);
+	assert_int_equal(result, 0x00ff);
+
+	data[0] = 0xff;
+	data[1] = 0x00;
+	result = PULL_BE_U16(data, 0);
+	assert_int_equal(result, 0xff00);
+
+	data[0] = 0xff;
+	data[1] = 0xff;
+	result = PULL_BE_U16(data, 0);
+	assert_int_equal(result, 0xffff);
+}
+
+static void torture_pull_be_u32(void **state)
+{
+	uint8_t data[4] = {0, 0, 0, 0};
+	uint32_t result;
+
+	(void)state;
+
+	result = PULL_BE_U32(data, 0);
+	assert_int_equal(result, 0);
+
+	data[0] = 0x00;
+	data[1] = 0x00;
+	data[2] = 0x00;
+	data[3] = 0x2a;
+	result = PULL_BE_U32(data, 0);
+	assert_int_equal(result, 42);
+
+	data[0] = 0x00;
+	data[1] = 0x00;
+	data[2] = 0x00;
+	data[3] = 0xff;
+	result = PULL_BE_U32(data, 0);
+	assert_int_equal(result, 0x00ff);
+
+	data[0] = 0x00;
+	data[1] = 0x00;
+	data[2] = 0xff;
+	data[3] = 0x00;
+	result = PULL_BE_U32(data, 0);
+	assert_int_equal(result, 0xff00);
+
+	data[0] = 0x00;
+	data[1] = 0xff;
+	data[2] = 0x00;
+	data[3] = 0x00;
+	result = PULL_BE_U32(data, 0);
+	assert_int_equal(result, 0xff0000);
+
+	data[0] = 0xff;
+	data[1] = 0x00;
+	data[2] = 0x00;
+	data[3] = 0x00;
+	result = PULL_BE_U32(data, 0);
+	assert_int_equal(result, 0xff000000);
+
+	data[0] = 0xff;
+	data[1] = 0xff;
+	data[2] = 0xff;
+	data[3] = 0xff;
+	result = PULL_BE_U32(data, 0);
+	assert_int_equal(result, 0xffffffff);
+}
+
+static void torture_push_be_u8(void **state)
+{
+	uint8_t data[4] = {0, 0, 0, 0};
+	uint8_t data2[4] = {42, 42, 42, 42};
+
+	(void)state;
+
+	PUSH_BE_U8(data, 0, 42);
+	PUSH_BE_U8(data, 1, 42);
+	PUSH_BE_U8(data, 2, 42);
+	PUSH_BE_U8(data, 3, 42);
+	assert_memory_equal(data, data2, sizeof(data));
+}
+
+static void torture_push_be_u16(void **state)
+{
+	uint8_t data[4] = {0, 0, 0, 0};
+	uint8_t data2[4] = {0x7f, 0xa6, 0x00, 0x2a};
+	uint16_t result;
+
+	(void)state;
+
+	PUSH_BE_U16(data, 0, 32678);
+	PUSH_BE_U16(data, 2, 42);
+	assert_memory_equal(data, data2, sizeof(data));
+
+	result = PULL_BE_U16(data, 2);
+	assert_int_equal(result, 42);
+
+	result = PULL_BE_U16(data, 0);
+	assert_int_equal(result, 32678);
+}
+
+static void torture_push_be_u32(void **state)
+{
+	uint8_t data[8] = {0};
+	uint8_t data2[8] = {0x00, 0x00, 0x7f, 0xa6, 0x00, 0x00, 0x00, 0x2a};
+	uint32_t result;
+
+	(void)state;
+
+	PUSH_BE_U32(data, 0, 32678);
+	PUSH_BE_U32(data, 4, 42);
+	assert_memory_equal(data, data2, sizeof(data));
+
+	result = PULL_BE_U32(data, 4);
+	assert_int_equal(result, 42);
+
+	result = PULL_BE_U32(data, 0);
+	assert_int_equal(result, 32678);
+
+	PUSH_BE_U32(data, 0, 0xfffefffe);
+	result = PULL_BE_U32(data, 0);
+	assert_int_equal(result, 0xfffefffe);
+}
+
+static void torture_push_be_u64(void **state)
+{
+	uint8_t data[16] = {0};
+	uint64_t result;
+
+	(void)state;
+
+	PUSH_BE_U64(data, 0, 32678);
+
+	result = PULL_BE_U64(data, 0);
+	assert_int_equal(result, 32678);
+
+	PUSH_LE_U64(data, 8, 0xfffefffe);
+
+	result = PULL_LE_U64(data, 8);
+	assert_int_equal(result, 0xfffefffe);
+}
+
+int main(int argc, char *argv[])
+{
+	int rc;
+	const struct CMUnitTest tests[] = {
+		cmocka_unit_test(torture_pull_le_u8),
+		cmocka_unit_test(torture_pull_le_u16),
+		cmocka_unit_test(torture_pull_le_u32),
+
+		cmocka_unit_test(torture_push_le_u8),
+		cmocka_unit_test(torture_push_le_u16),
+		cmocka_unit_test(torture_push_le_u32),
+		cmocka_unit_test(torture_push_le_u64),
+
+		/* BIG ENDIAN */
+		cmocka_unit_test(torture_pull_be_u8),
+		cmocka_unit_test(torture_pull_be_u16),
+		cmocka_unit_test(torture_pull_be_u32),
+
+		cmocka_unit_test(torture_push_be_u8),
+		cmocka_unit_test(torture_push_be_u16),
+		cmocka_unit_test(torture_push_be_u32),
+		cmocka_unit_test(torture_push_be_u64),
+	};
+
+	if (argc == 2) {
+		cmocka_set_test_filter(argv[1]);
+	}
+	cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+
+	rc = cmocka_run_group_tests(tests, NULL, NULL);
+
+	return rc;
+}
diff --git a/lib/util/wscript_build b/lib/util/wscript_build
index 8fc402062fb..aa08b3887ee 100644
--- a/lib/util/wscript_build
+++ b/lib/util/wscript_build
@@ -126,7 +126,7 @@ else:
                     tevent_debug.c memcache.c unix_match.c tfork.c''',
                   deps='samba-util-core DYNCONFIG close-low-fd tiniparser genrand util_str_hex',
                   public_deps='talloc tevent execinfo pthread LIBCRYPTO charset util_setid',
-                  public_headers='debug.h attr.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h string_wrappers.h idtree.h idtree_random.h blocking.h signal.h substitute.h fault.h genrand.h tfork.h',
+                  public_headers='debug.h attr.h bytearray.h byteorder.h data_blob.h memory.h safe_string.h time.h talloc_stack.h string_wrappers.h idtree.h idtree_random.h blocking.h signal.h substitute.h fault.h genrand.h tfork.h',
                   header_path= [ ('dlinklist.h samba_util.h', '.'), ('*', 'util') ],
                   local_include=False,
                   vnum='0.0.1',
@@ -234,3 +234,9 @@ else:
                      deps='cmocka replace samba-util',
                      local_include=False,
                      install=False)
+
+    bld.SAMBA_BINARY('test_bytearray',
+                     source='tests/test_bytearray.c',
+                     deps='cmocka replace samba-util',
+                     local_include=False,
+                     install=False)
diff --git a/selftest/tests.py b/selftest/tests.py
index 3de981f7e13..a2d0ff5d3c6 100644
--- a/selftest/tests.py
+++ b/selftest/tests.py
@@ -206,5 +206,7 @@ plantestsuite("samba.unittests.kerberos", "none",
               [os.path.join(bindir(), "test_kerberos")])
 plantestsuite("samba.unittests.ms_fnmatch", "none",
               [os.path.join(bindir(), "default/lib/util/test_ms_fnmatch")])
+plantestsuite("samba.unittests.bytearray", "none",
+              [os.path.join(bindir(), "default/lib/util/test_bytearray")])
 plantestsuite("samba.unittests.ntlm_check", "none",
               [os.path.join(bindir(), "default/libcli/auth/test_ntlm_check")])
-- 
2.19.2


>From 52d6799cabe2957a5a019e5724aa6ef184105ce0 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 20 Dec 2018 10:01:03 +0100
Subject: [PATCH 2/7] lib:util: Remove unused ALIGN marcos from byteorder.h

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/util/byteorder.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/lib/util/byteorder.h b/lib/util/byteorder.h
index 8656035693d..3933926cf54 100644
--- a/lib/util/byteorder.h
+++ b/lib/util/byteorder.h
@@ -179,11 +179,6 @@ static __inline__ void st_le32(uint32_t *addr, const uint32_t val)
 #define RSBVAL(buf,pos,val) SBVAL(buf,pos,BREV(val))
 #define RSBVALS(buf,pos,val) SBVALS(buf,pos,BREV(val))
 
-/* Alignment macros. */
-#define ALIGN4(p,base) ((p) + ((4 - (PTR_DIFF((p), (base)) & 3)) & 3))
-#define ALIGN2(p,base) ((p) + ((2 - (PTR_DIFF((p), (base)) & 1)) & 1))
-
-
 /* macros for accessing SMB protocol elements */
 #define VWV(vwv) ((vwv)*2)
 
-- 
2.19.2


>From e0c5eb00793aed4cd1a0d795a4830850dbb5afcf Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 20 Dec 2018 11:21:00 +0100
Subject: [PATCH 3/7] lib:util: Use _DATA_BYTE(_CONST) from bytearray.h

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/util/byteorder.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/util/byteorder.h b/lib/util/byteorder.h
index 3933926cf54..e99bc576904 100644
--- a/lib/util/byteorder.h
+++ b/lib/util/byteorder.h
@@ -20,6 +20,8 @@
 #ifndef _BYTEORDER_H
 #define _BYTEORDER_H
 
+#include "bytearray.h"
+
 /*
    This file implements macros for machine independent short and 
    int manipulation
@@ -123,8 +125,8 @@ static __inline__ void st_le32(uint32_t *addr, const uint32_t val)
 #define USE_ASM_BYTEORDER 0
 #endif
 
-#define CVAL(buf,pos) ((unsigned int)(((const uint8_t *)(buf))[pos]))
-#define CVAL_NC(buf,pos) (((uint8_t *)(buf))[pos]) /* Non-const version of CVAL */
+#define CVAL(buf,pos) ((uint32_t)_DATA_BYTE_CONST(buf, pos))
+#define CVAL_NC(buf,pos) _DATA_BYTE(buf, pos) /* Non-const version of CVAL */
 #define PVAL(buf,pos) (CVAL(buf,pos))
 #define SCVAL(buf,pos,val) (CVAL_NC(buf,pos) = (val))
 
-- 
2.19.2


>From 4746cbb0354d13d23bb0283b3fca8ae4017073fb Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 20 Dec 2018 11:22:56 +0100
Subject: [PATCH 4/7] lib:util: Use PULL_LE_(U16|U32) for SVAL and IVAL

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/util/byteorder.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/util/byteorder.h b/lib/util/byteorder.h
index e99bc576904..3898bf87b97 100644
--- a/lib/util/byteorder.h
+++ b/lib/util/byteorder.h
@@ -144,8 +144,8 @@ static __inline__ void st_le32(uint32_t *addr, const uint32_t val)
 
 #else /* not USE_ASM_BYTEORDER */
 
-#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
-#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
+#define SVAL(buf,pos) (uint32_t)PULL_LE_U16(buf, pos)
+#define IVAL(buf,pos) PULL_LE_U32(buf, pos)
 #define SSVALX(buf,pos,val) (CVAL_NC(buf,pos)=(uint8_t)((val)&0xFF),CVAL_NC(buf,pos+1)=(uint8_t)((val)>>8))
 #define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
 #define SVALS(buf,pos) ((int16_t)SVAL(buf,pos))
-- 
2.19.2


>From d362eabf8372126e12499fadf68573657a62c97b Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 20 Dec 2018 11:23:46 +0100
Subject: [PATCH 5/7] lib:util: Use PUSH_LE_(U16|U32) for S(S|I)VAL

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/util/byteorder.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/util/byteorder.h b/lib/util/byteorder.h
index 3898bf87b97..a5a094f3401 100644
--- a/lib/util/byteorder.h
+++ b/lib/util/byteorder.h
@@ -150,8 +150,8 @@ static __inline__ void st_le32(uint32_t *addr, const uint32_t val)
 #define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
 #define SVALS(buf,pos) ((int16_t)SVAL(buf,pos))
 #define IVALS(buf,pos) ((int32_t)IVAL(buf,pos))
-#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16_t)(val)))
-#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32_t)(val)))
+#define SSVAL(buf,pos,val) PUSH_LE_U16(buf, pos, val)
+#define SIVAL(buf,pos,val) PUSH_LE_U32(buf, pos, val)
 #define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16_t)(val)))
 #define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32_t)(val)))
 
-- 
2.19.2


>From 00bb687393a61a43a27bc9248505bccd756527f5 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 20 Dec 2018 11:57:08 +0100
Subject: [PATCH 6/7] lib:util: Use PUSH_LE_(U16|U32) for S(I|S)VALS

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/util/byteorder.h | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/lib/util/byteorder.h b/lib/util/byteorder.h
index a5a094f3401..a5618214b0a 100644
--- a/lib/util/byteorder.h
+++ b/lib/util/byteorder.h
@@ -146,14 +146,12 @@ static __inline__ void st_le32(uint32_t *addr, const uint32_t val)
 
 #define SVAL(buf,pos) (uint32_t)PULL_LE_U16(buf, pos)
 #define IVAL(buf,pos) PULL_LE_U32(buf, pos)
-#define SSVALX(buf,pos,val) (CVAL_NC(buf,pos)=(uint8_t)((val)&0xFF),CVAL_NC(buf,pos+1)=(uint8_t)((val)>>8))
-#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
 #define SVALS(buf,pos) ((int16_t)SVAL(buf,pos))
 #define IVALS(buf,pos) ((int32_t)IVAL(buf,pos))
 #define SSVAL(buf,pos,val) PUSH_LE_U16(buf, pos, val)
 #define SIVAL(buf,pos,val) PUSH_LE_U32(buf, pos, val)
-#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16_t)(val)))
-#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32_t)(val)))
+#define SSVALS(buf,pos,val) PUSH_LE_U16(buf, pos, val)
+#define SIVALS(buf,pos,val) PUSH_LE_U32(buf, pos, val)
 
 #endif /* not USE_ASM_BYTEORDER */
 
-- 
2.19.2


>From 0b436bcd1fedf2aaba7d1ced9cd64e4d48077413 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Thu, 20 Dec 2018 11:24:29 +0100
Subject: [PATCH 7/7] lib:util: Use (PULL|PUSH)_BE_(U16|U32|U64) for R*VAL*

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/util/byteorder.h | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/lib/util/byteorder.h b/lib/util/byteorder.h
index a5618214b0a..93e77fef462 100644
--- a/lib/util/byteorder.h
+++ b/lib/util/byteorder.h
@@ -156,9 +156,9 @@ static __inline__ void st_le32(uint32_t *addr, const uint32_t val)
 #endif /* not USE_ASM_BYTEORDER */
 
 /* 64 bit macros */
-#define BVAL(p, ofs) (IVAL(p,ofs) | (((uint64_t)IVAL(p,(ofs)+4)) << 32))
+#define BVAL(p, ofs) PULL_LE_U64(p, ofs)
 #define BVALS(p, ofs) ((int64_t)BVAL(p,ofs))
-#define SBVAL(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,((uint64_t)(v))>>32))
+#define SBVAL(p, ofs, v) PUSH_LE_U64(p, ofs, v)
 #define SBVALS(p, ofs, v) (SBVAL(p,ofs,(uint64_t)v))
 
 /* now the reverse routines - these are used in nmb packets (mostly) */
@@ -166,18 +166,18 @@ static __inline__ void st_le32(uint32_t *addr, const uint32_t val)
 #define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16)))
 #define BREV(x) ((IREV((uint64_t)x)<<32) | (IREV(((uint64_t)x)>>32)))
 
-#define RSVAL(buf,pos) SREV(SVAL(buf,pos))
-#define RSVALS(buf,pos) SREV(SVALS(buf,pos))
-#define RIVAL(buf,pos) IREV(IVAL(buf,pos))
-#define RIVALS(buf,pos) IREV(IVALS(buf,pos))
-#define RBVAL(buf,pos) BREV(BVAL(buf,pos))
-#define RBVALS(buf,pos) BREV(BVALS(buf,pos))
-#define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val))
-#define RSSVALS(buf,pos,val) SSVALS(buf,pos,SREV(val))
-#define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val))
-#define RSIVALS(buf,pos,val) SIVALS(buf,pos,IREV(val))
-#define RSBVAL(buf,pos,val) SBVAL(buf,pos,BREV(val))
-#define RSBVALS(buf,pos,val) SBVALS(buf,pos,BREV(val))
+#define RSVAL(buf,pos) (uint32_t)PULL_BE_U16(buf, pos)
+#define RSVALS(buf,pos) PULL_BE_U16(buf, pos)
+#define RIVAL(buf,pos) PULL_BE_U32(buf, pos)
+#define RIVALS(buf,pos) PULL_BE_U32(buf, pos)
+#define RBVAL(buf,pos) PULL_BE_U64(buf, pos)
+#define RBVALS(buf,pos) PULL_BE_U64(buf, pos)
+#define RSSVAL(buf,pos,val) PUSH_BE_U16(buf, pos, val)
+#define RSSVALS(buf,pos,val) PUSH_BE_U16(buf, pos, val)
+#define RSIVAL(buf,pos,val) PUSH_BE_U32(buf, pos, val)
+#define RSIVALS(buf,pos,val) PUSH_BE_U32(buf, pos, val)
+#define RSBVAL(buf,pos,val) PUSH_BE_U64(buf, pos, val)
+#define RSBVALS(buf,pos,val) PUSH_BE_U64(buf, pos, val)
 
 /* macros for accessing SMB protocol elements */
 #define VWV(vwv) ((vwv)*2)
-- 
2.19.2



More information about the samba-technical mailing list