summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2011-08-24 12:07:43 -0700
committerRandall Spangler <rspangler@chromium.org>2011-08-24 13:50:51 -0700
commit1f5d53f7bd4dc590b47f21f858d021ac53190a17 (patch)
tree2160cc9bada9e16ffac4d8282942e2927186450c
parent0a9977e161ce6ad6b11935dfb05ae840bf758078 (diff)
downloadvboot-1f5d53f7bd4dc590b47f21f858d021ac53190a17.tar.gz
Add tests for vboot_reference stateful_util.c
BUG=chromium-os:17564 TEST=make && make runtests Change-Id: I5d55be2dfead0c5d7af72841cbd6c65485685cd6 Reviewed-on: http://gerrit.chromium.org/gerrit/6596 Reviewed-by: Stefan Reinauer <reinauer@chromium.org> Tested-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--firmware/lib/include/stateful_util.h14
-rw-r--r--firmware/lib/stateful_util.c6
-rw-r--r--tests/Makefile2
-rw-r--r--tests/stateful_util_tests.c302
-rw-r--r--tests/test_common.c19
-rw-r--r--tests/test_common.h8
-rw-r--r--tests/utility_tests.c2
7 files changed, 345 insertions, 8 deletions
diff --git a/firmware/lib/include/stateful_util.h b/firmware/lib/include/stateful_util.h
index 5630534f..980b12b0 100644
--- a/firmware/lib/include/stateful_util.h
+++ b/firmware/lib/include/stateful_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -19,10 +19,14 @@ typedef struct MemcpyState {
uint8_t overrun; /* Flag set to 1 when an overrun occurs. */
} MemcpyState;
+/* Initialize a stateful buffer struct to point to the buffer, with
+ * the specified remaining length in bytes. */
+void StatefulInit(MemcpyState* state, void* buf, uint64_t len);
+
/* Skip [len] bytes only if there's enough data to skip according
* to [state].
* On success, return a meaningless but non-NULL pointer and updates [state].
- * On failure, return NULL, set remaining_len in state to -1.
+ * On failure, return NULL, set state->overrun to 1.
*
* Useful for iterating through a binary blob to populate a struct. After the
* first failure (buffer overrun), successive calls will always fail.
@@ -32,7 +36,7 @@ void* StatefulSkip(MemcpyState* state, uint64_t len);
/* Copy [len] bytes into [dst] only if there's enough data to read according
* to [state].
* On success, return [dst] and update [state].
- * On failure, return NULL, set remaining len in state to -1.
+ * On failure, return NULL, set state->overrun to 1.
*
* Useful for iterating through a binary blob to populate a struct. After the
* first failure (buffer overrun), successive calls will always fail.
@@ -42,7 +46,7 @@ void* StatefulMemcpy(MemcpyState* state, void* dst, uint64_t len);
/* Like StatefulMemcpy() but copies in the opposite direction, populating
* data from [src] into the buffer encapsulated in state [state].
* On success, return [src] and update [state].
- * On failure, return NULL, set remaining_len in state to -1.
+ * On failure, return NULL, set state->overrun to 1.
*
* Useful for iterating through a structure to populate a binary blob. After the
* first failure (buffer overrun), successive calls will always fail.
@@ -52,7 +56,7 @@ const void* StatefulMemcpy_r(MemcpyState* state, const void* src, uint64_t len);
/* Like StatefulMemcpy_r() but fills a portion of the encapsulated buffer with
* a constant value.
* On success, return a meaningless but non-NULL pointer and updates [state].
- * On failure, return NULL, set remaining_len in state to -1.
+ * On failure, return NULL, set state->overrun to 1.
*
* After the first failure (buffer overrun), successive calls will always fail.
*/
diff --git a/firmware/lib/stateful_util.c b/firmware/lib/stateful_util.c
index 1d824fc2..01a7d641 100644
--- a/firmware/lib/stateful_util.c
+++ b/firmware/lib/stateful_util.c
@@ -9,6 +9,12 @@
#include "utility.h"
+void StatefulInit(MemcpyState* state, void* buf, uint64_t len) {
+ state->remaining_buf = buf;
+ state->remaining_len = len;
+ state->overrun = 0;
+}
+
void* StatefulSkip(MemcpyState* state, uint64_t len) {
if (state->overrun)
return NULL;
diff --git a/tests/Makefile b/tests/Makefile
index 01729598..235ba957 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -15,6 +15,7 @@ TEST_NAMES = cgptlib_test \
rsa_verify_benchmark \
sha_benchmark \
sha_tests \
+ stateful_util_tests \
utility_string_tests \
utility_tests \
vboot_common_tests \
@@ -92,6 +93,7 @@ runcryptotests:
# Run other misc tests
runmisctests:
./run_vbutil_tests.sh
+ ${BUILD_ROOT}/stateful_util_tests
${BUILD_ROOT}/utility_string_tests
${BUILD_ROOT}/utility_tests
diff --git a/tests/stateful_util_tests.c b/tests/stateful_util_tests.c
new file mode 100644
index 00000000..077a2ae9
--- /dev/null
+++ b/tests/stateful_util_tests.c
@@ -0,0 +1,302 @@
+/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Tests for statful_util functions.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define _STUB_IMPLEMENTATION_ /* So we can use memset() ourselves */
+
+#include "stateful_util.h"
+#include "test_common.h"
+#include "utility.h"
+#include "vboot_common.h"
+
+
+/* Test StatefulInit */
+static void StatefulInitTest(void) {
+ MemcpyState s;
+ char buf[128];
+
+ memset(&s, 0, sizeof(s));
+ s.overrun = 1;
+ StatefulInit(&s, buf, 128);
+ TEST_EQ(0, s.overrun, "StatefulInit() overrun");
+ TEST_EQ(128, s.remaining_len, "StatefulInit() len");
+ TEST_PTR_EQ(buf, s.remaining_buf, "StatefulInit() buf");
+}
+
+
+/* Test StatefulSkip */
+static void StatefulSkipTest(void) {
+ MemcpyState s;
+ char buf[128];
+
+ /* Small skip */
+ StatefulInit(&s, buf, 128);
+ TEST_PTR_EQ(&s, StatefulSkip(&s, 5), "StatefulSkip(5) retval");
+ TEST_EQ(128 - 5, s.remaining_len, "StatefulSkip(5) len");
+ TEST_PTR_EQ(buf + 5, s.remaining_buf, "StatefulSkip(5) buf");
+ TEST_EQ(0, s.overrun, "StatefulSkip(5) overrun");
+
+ /* Use entire buffer */
+ StatefulInit(&s, buf, 128);
+ TEST_PTR_EQ(&s, StatefulSkip(&s, 128), "StatefulSkip(all) retval");
+ TEST_EQ(0, s.remaining_len, "StatefulSkip(all) len");
+ TEST_PTR_EQ(buf + 128, s.remaining_buf, "StatefulSkip(all) buf");
+ TEST_EQ(0, s.overrun, "StatefulSkip(all) overrun");
+
+ /* Zero-length skip is ok (but meaningless) */
+ TEST_PTR_EQ(&s, StatefulSkip(&s, 0), "StatefulSkip(0) retval");
+ TEST_EQ(0, s.remaining_len, "StatefulSkip(0) len");
+ TEST_PTR_EQ(buf + 128, s.remaining_buf, "StatefulSkip(0) buf");
+ TEST_EQ(0, s.overrun, "StatefulSkip(0) overrun");
+
+ /* Can't use even one byte past that */
+ TEST_PTR_EQ(NULL, StatefulSkip(&s, 1), "StatefulSkip(+1) retval");
+ TEST_EQ(0, s.remaining_len, "StatefulSkip(+1) len");
+ TEST_EQ(1, s.overrun, "StatefulSkip(+1) overrun");
+
+ /* Overrun */
+ StatefulInit(&s, buf, 128);
+ TEST_PTR_EQ(NULL, StatefulSkip(&s, 256), "StatefulSkip(256) retval");
+ TEST_EQ(1, s.overrun, "StatefulSkip(256) overrun");
+ /* Once overrun, always overrun, even if we now ask for a small skip */
+ TEST_PTR_EQ(NULL, StatefulSkip(&s, 1), "StatefulSkip(256+1) retval");
+ TEST_EQ(1, s.overrun, "StatefulSkip(256+1) overrun");
+
+ /* Overrun with potential wraparound */
+ StatefulInit(&s, buf, 128);
+ TEST_PTR_EQ(NULL, StatefulSkip(&s, -1), "StatefulSkip(-1) retval");
+ TEST_EQ(1, s.overrun, "StatefulSkip(-1) overrun");
+}
+
+
+/* Test StatefulMemset_r */
+static void StatefulMemset_rTest(void) {
+ MemcpyState s;
+ char buf[129];
+ char want[129];
+
+ memset(want, 0, sizeof(want));
+ memset(buf, 0, sizeof(buf));
+
+ /* Small sets */
+ StatefulInit(&s, buf, 128);
+ TEST_PTR_EQ(&s, StatefulMemset_r(&s, 'A', 5), "StatefulMemset_r(5) retval");
+ TEST_EQ(128 - 5, s.remaining_len, "StatefulMemset_r(5) len");
+ TEST_PTR_EQ(buf + 5, s.remaining_buf, "StatefulMemset_r(5) buf");
+ /* Using strcmp() is a convenient way to check that we didn't
+ * overwrite the 0-byte following what we expected to set. */
+ TEST_EQ(0, strcmp("AAAAA", buf), "StatefulMemset_r(5) contents");
+ TEST_EQ(0, s.overrun, "StatefulMemset_r(5) overrun");
+ TEST_PTR_EQ(&s, StatefulMemset_r(&s, 'B', 3), "StatefulMemset_r(3) retval");
+ TEST_EQ(0, strcmp("AAAAABBB", buf), "StatefulMemset_r(3) contents");
+
+ /* Use entire buffer */
+ StatefulInit(&s, buf, 128);
+ TEST_PTR_EQ(&s, StatefulMemset_r(&s, 'C', 128),
+ "StatefulMemset_r(all) retval");
+ TEST_EQ(0, s.remaining_len, "StatefulMemset_r(all) len");
+ TEST_PTR_EQ(buf + 128, s.remaining_buf, "StatefulMemset_r(all) buf");
+ TEST_EQ(0, s.overrun, "StatefulMemset_r(all) overrun");
+ memset(want, 'C', 128);
+ TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(all) contents");
+
+ /* Zero-length set is ok (but meaningless) */
+ TEST_PTR_EQ(&s, StatefulMemset_r(&s, 'D', 0), "StatefulMemset_r(0) retval");
+ TEST_EQ(0, s.remaining_len, "StatefulMemset_r(0) len");
+ TEST_PTR_EQ(buf + 128, s.remaining_buf, "StatefulMemset_r(0) buf");
+ TEST_EQ(0, s.overrun, "StatefulMemset_r(0) overrun");
+ TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(0) contents");
+
+ /* Can't use even one byte past that */
+ TEST_PTR_EQ(NULL, StatefulMemset_r(&s, 'E', 1),
+ "StatefulMemset_r(+1) retval");
+ TEST_EQ(0, s.remaining_len, "StatefulMemset_r(+1) len");
+ TEST_EQ(1, s.overrun, "StatefulMemset_r(+1) overrun");
+ TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(+1) contents");
+
+ /* Overrun */
+ StatefulInit(&s, buf, 128);
+ TEST_PTR_EQ(NULL, StatefulMemset_r(&s, 'F', 256),
+ "StatefulMemset_r(256) retval");
+ TEST_EQ(1, s.overrun, "StatefulMemset_r(256) overrun");
+ /* Once overrun, always overrun, even if we now ask for a small skip */
+ TEST_PTR_EQ(NULL, StatefulMemset_r(&s, 'G', 1),
+ "StatefulMemset_r(256+1) retval");
+ TEST_EQ(1, s.overrun, "StatefulMemset_r(256+1) overrun");
+ TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(+1) contents");
+
+ /* Overrun with potential wraparound */
+ StatefulInit(&s, buf, 128);
+ TEST_PTR_EQ(NULL, StatefulMemset_r(&s, 'H', -1),
+ "StatefulMemset_r(-1) retval");
+ TEST_EQ(1, s.overrun, "StatefulMemset_r(-1) overrun");
+ TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemset_r(+1) contents");
+}
+
+
+/* Test StatefulMemcpy_r */
+static void StatefulMemcpy_rTest(void) {
+ MemcpyState s;
+ char buf[129];
+ char want[129];
+ char* src1 = "Doogie";
+ char* src2 = "Howserrr";
+ char* src3 = "WholeBuffr";
+
+ memset(want, 0, sizeof(want));
+ memset(buf, 0, sizeof(buf));
+
+ /* Small copies */
+ StatefulInit(&s, buf, 128);
+ TEST_PTR_EQ(src1, StatefulMemcpy_r(&s, src1, 6),
+ "StatefulMemcpy_r(6) retval");
+ TEST_EQ(128 - 6, s.remaining_len, "StatefulMemcpy_r(6) len");
+ TEST_PTR_EQ(buf + 6, s.remaining_buf, "StatefulMemcpy_r(6) buf");
+ /* Using strcmp() is a convenient way to check that we didn't
+ * overwrite the 0-byte following what we expected to copy. */
+ TEST_EQ(0, strcmp("Doogie", buf), "StatefulMemcpy_r(6) contents");
+ TEST_EQ(0, s.overrun, "StatefulMemcpy_r(6) overrun");
+ TEST_PTR_EQ(src2, StatefulMemcpy_r(&s, src2, 8),
+ "StatefulMemcpy_r(8) retval");
+ TEST_EQ(0, strcmp("DoogieHowserrr", buf), "StatefulMemcpy_r(8) contents");
+
+ /* Use entire buffer */
+ memset(buf, 42, sizeof(buf));
+ StatefulInit(&s, buf, 10);
+ TEST_PTR_EQ(src3, StatefulMemcpy_r(&s, src3, 10),
+ "StatefulMemcpy_r(all) retval");
+ TEST_EQ(0, s.remaining_len, "StatefulMemcpy_r(all) len");
+ TEST_PTR_EQ(buf + 10, s.remaining_buf, "StatefulMemcpy_r(all) buf");
+ TEST_EQ(0, s.overrun, "StatefulMemcpy_r(all) overrun");
+ TEST_EQ(0, memcmp(src3, buf, 10), "StatefulMemcpy_r(all) contents");
+ TEST_EQ(42, buf[10], "StatefulMemcpy_r(all) contents+1");
+
+ /* Zero-length copy is ok (but meaningless) */
+ TEST_PTR_EQ(src1, StatefulMemcpy_r(&s, src1, 0),
+ "StatefulMemcpy_r(0) retval");
+ TEST_EQ(0, s.remaining_len, "StatefulMemcpy_r(0) len");
+ TEST_PTR_EQ(buf + 10, s.remaining_buf, "StatefulMemcpy_r(0) buf");
+ TEST_EQ(0, s.overrun, "StatefulMemcpy_r(0) overrun");
+ TEST_EQ(42, buf[10], "StatefulMemcpy_r(0) contents+1");
+
+ /* Can't use even one byte past that */
+ TEST_PTR_EQ(NULL, StatefulMemcpy_r(&s, src1, 1),
+ "StatefulMemcpy_r(+1) retval");
+ TEST_EQ(0, s.remaining_len, "StatefulMemcpy_r(+1) len");
+ TEST_EQ(1, s.overrun, "StatefulMemcpy_r(+1) overrun");
+ TEST_EQ(42, buf[10], "StatefulMemcpy_r(+1) contents");
+
+ /* Overrun */
+ memset(buf, 0, sizeof(buf));
+ StatefulInit(&s, buf, 8);
+ TEST_PTR_EQ(NULL, StatefulMemcpy_r(&s, "MoreThan8", 9),
+ "StatefulMemcpy_r(9) retval");
+ TEST_EQ(1, s.overrun, "StatefulMemcpy_r(9) overrun");
+ /* Once overrun, always overrun, even if we now ask for a small skip */
+ TEST_PTR_EQ(NULL, StatefulMemcpy_r(&s, "Less", 4),
+ "StatefulMemcpy_r(9+1) retval");
+ TEST_EQ(1, s.overrun, "StatefulMemcpy_r(9+1) overrun");
+ TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemcpy_r(+1) contents");
+
+ /* Overrun with potential wraparound */
+ StatefulInit(&s, buf, 128);
+ TEST_PTR_EQ(NULL, StatefulMemcpy_r(&s, "FOO", -1),
+ "StatefulMemcpy_r(-1) retval");
+ TEST_EQ(1, s.overrun, "StatefulMemcpy_r(-1) overrun");
+ TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemcpy_r(+1) contents");
+}
+
+
+/* Test StatefulMemcpy */
+static void StatefulMemcpyTest(void) {
+ MemcpyState s;
+ char buf[129];
+ char want[129];
+ char* src1 = "ThisIsATest";
+ char* src2 = "ThisIsOnlyATest";
+
+ memset(want, 0, sizeof(want));
+ memset(buf, 0, sizeof(buf));
+
+ /* Small copies */
+ StatefulInit(&s, src1, 12);
+ TEST_PTR_EQ(buf, StatefulMemcpy(&s, buf, 6), "StatefulMemcpy(6) retval");
+ TEST_EQ(6, s.remaining_len, "StatefulMemcpy(6) len");
+ TEST_PTR_EQ(src1 + 6, s.remaining_buf, "StatefulMemcpy(6) buf");
+ /* Using strcmp() is a convenient way to check that we didn't
+ * overwrite the 0-byte following what we expected to copy. */
+ TEST_EQ(0, strcmp("ThisIs", buf), "StatefulMemcpy(6) contents");
+ TEST_EQ(0, s.overrun, "StatefulMemcpy(6) overrun");
+ TEST_PTR_EQ(buf, StatefulMemcpy(&s, buf, 5), "StatefulMemcpy(5) retval");
+ /* Note that we shouldn't have copied the last byte out of the
+ * stateful buffer, so we don't overwrite the last character of the
+ * string that was in buf. */
+ TEST_EQ(0, strcmp("ATests", buf), "StatefulMemcpy(5) contents");
+
+ /* Use entire buffer */
+ memset(buf, 1, sizeof(buf));
+ StatefulInit(&s, src2, 16);
+ TEST_PTR_EQ(buf, StatefulMemcpy(&s, buf, 16), "StatefulMemcpy(all) retval");
+ TEST_EQ(0, s.remaining_len, "StatefulMemcpy(all) len");
+ TEST_PTR_EQ(src2 + 16, s.remaining_buf, "StatefulMemcpy(all) buf");
+ TEST_EQ(0, s.overrun, "StatefulMemcpy(all) overrun");
+ TEST_EQ(0, strcmp(src2, buf), "StatefulMemcpy(all) contents");
+
+ /* Zero-length copy is ok (but meaningless) */
+ TEST_PTR_EQ(buf, StatefulMemcpy(&s, buf, 0),
+ "StatefulMemcpy(0) retval");
+ TEST_EQ(0, s.remaining_len, "StatefulMemcpy(0) len");
+ TEST_PTR_EQ(src2 + 16, s.remaining_buf, "StatefulMemcpy(0) buf");
+ TEST_EQ(0, s.overrun, "StatefulMemcpy(0) overrun");
+ TEST_EQ(0, strcmp(src2, buf), "StatefulMemcpy(0) contents");
+
+ /* Can't use even one byte past that */
+ TEST_PTR_EQ(NULL, StatefulMemcpy(&s, buf, 1),
+ "StatefulMemcpy(+1) retval");
+ TEST_EQ(0, s.remaining_len, "StatefulMemcpy(+1) len");
+ TEST_EQ(1, s.overrun, "StatefulMemcpy(+1) overrun");
+ TEST_EQ(0, strcmp(src2, buf), "StatefulMemcpy(+1) contents");
+
+ /* Overrun */
+ memset(buf, 0, sizeof(buf));
+ StatefulInit(&s, "Small", 5);
+ TEST_PTR_EQ(NULL, StatefulMemcpy(&s, buf, 9), "StatefulMemcpy(9) retval");
+ TEST_EQ(1, s.overrun, "StatefulMemcpy(9) overrun");
+ /* Once overrun, always overrun, even if we now ask for a small skip */
+ TEST_PTR_EQ(NULL, StatefulMemcpy(&s, buf, 4),
+ "StatefulMemcpy(9+1) retval");
+ TEST_EQ(1, s.overrun, "StatefulMemcpy(9+1) overrun");
+ TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemcpy(+1) contents");
+
+ /* Overrun with potential wraparound */
+ StatefulInit(&s, "Larger", 6);
+ TEST_PTR_EQ(NULL, StatefulMemcpy(&s, buf, -1), "StatefulMemcpy(-1) retval");
+ TEST_EQ(1, s.overrun, "StatefulMemcpy(-1) overrun");
+ TEST_EQ(0, memcmp(want, buf, sizeof(want)), "StatefulMemcpy(+1) contents");
+}
+
+
+/* disable MSVC warnings on unused arguments */
+__pragma(warning (disable: 4100))
+
+int main(int argc, char* argv[]) {
+ int error_code = 0;
+
+ StatefulInitTest();
+ StatefulSkipTest();
+ StatefulMemset_rTest();
+ StatefulMemcpy_rTest();
+ StatefulMemcpyTest();
+
+ if (!gTestSuccess)
+ error_code = 255;
+
+ return error_code;
+}
diff --git a/tests/test_common.c b/tests/test_common.c
index e7e54933..6521fa0f 100644
--- a/tests/test_common.c
+++ b/tests/test_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
@@ -23,6 +23,7 @@ int TEST_EQ(int result, int expected_result, char* testname) {
}
else {
fprintf(stderr, "%s Test " COL_RED "FAILED\n" COL_STOP, testname);
+ fprintf(stderr, " Expected: %d, got: %d\n", expected_result, result);
gTestSuccess = 0;
return 0;
}
@@ -35,6 +36,22 @@ int TEST_NEQ(int result, int not_expected_result, char* testname) {
}
else {
fprintf(stderr, "%s Test " COL_RED "FAILED\n" COL_STOP, testname);
+ fprintf(stderr, " Didn't expect %d, but got it.\n", not_expected_result);
+ gTestSuccess = 0;
+ return 0;
+ }
+}
+
+int TEST_PTR_EQ(const void* result, const void* expected_result,
+ char* testname) {
+ if (result == expected_result) {
+ fprintf(stderr, "%s Test " COL_GREEN "PASSED\n" COL_STOP, testname);
+ return 1;
+ }
+ else {
+ fprintf(stderr, "%s Test " COL_RED "FAILED\n" COL_STOP, testname);
+ fprintf(stderr, " Expected: 0x%lx, got: 0x%lx\n", (long)expected_result,
+ (long)result);
gTestSuccess = 0;
return 0;
}
diff --git a/tests/test_common.h b/tests/test_common.h
index ed3e6039..532e7b2f 100644
--- a/tests/test_common.h
+++ b/tests/test_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
@@ -12,10 +12,16 @@ extern int gTestSuccess;
/* Return 1 if result is equal to expected_result, else return 0.
* Also update the global gTestSuccess flag if test fails. */
int TEST_EQ(int result, int expected_result, char* testname);
+
/* Return 0 if result is equal to not_expected_result, else return 1.
* Also update the global gTestSuccess flag if test fails. */
int TEST_NEQ(int result, int not_expected_result, char* testname);
+/* Return 1 if result is equal to expected_result, else return 0.
+ * Also update the global gTestSuccess flag if test fails. */
+int TEST_PTR_EQ(const void* result, const void* expected_result,
+ char* testname);
+
/* ANSI Color coding sequences.
*
* Don't use \e as MSC does not recognize it as a valid escape sequence.
diff --git a/tests/utility_tests.c b/tests/utility_tests.c
index b8a1da93..9fc1dab5 100644
--- a/tests/utility_tests.c
+++ b/tests/utility_tests.c
@@ -26,7 +26,7 @@ static void MemsetTest(void) {
/* Simple fill */
memset(want, 123, 5);
- TEST_EQ(0, dest - (char*)Memset(dest, 123, 5), "Memset() returns dest");
+ TEST_PTR_EQ(dest, Memset(dest, 123, 5), "Memset() returns dest");
TEST_EQ(0, memcmp(dest, want, 128), "Memset()");
/* Filling length 0 does nothing */