From ca62f3ea2b273eabd374d5dddb9de0e644f03d58 Mon Sep 17 00:00:00 2001
From: Fred Wright <fw@fwright.net>
Date: Wed, 23 Oct 2024 15:34:35 -0700
Subject: [PATCH] Add tests for alternate realpath() versions.

This ensures that all three versions of realpath() (two in 64-bit
builds) have test coverage.  The test for the impossible 64-bit
non-POSIX case is a dummy.

The 10.15 non-POSIX realpath() has a bug (unrelated to
legacy-support) causing the relevant test to fail.  A subsequent
commit excludes that case from the test.

This test uncovered real bugs in the former wrapper implementation.

TESTED:
Without the realpath() fix, fails on 10.5 and on 10.4 with later SDK.
With the fix, passes on all platforms (except as noted above).
---
 Makefile                      | 10 ++++++++++
 test/test_realpath.c          | 10 +++++++++-
 test/test_realpath_nonext.c   |  7 +++++++
 test/test_realpath_nonposix.c | 23 +++++++++++++++++++++++
 4 files changed, 49 insertions(+), 1 deletion(-)
 create mode 100644 test/test_realpath_nonext.c
 create mode 100644 test/test_realpath_nonposix.c

diff --git a/Makefile b/Makefile
index 9b4abf2..2dae10a 100644
--- a/Makefile
+++ b/Makefile
@@ -158,6 +158,9 @@ TESTSRUNS       := $(patsubst \
                      $(TESTNAMEPREFIX)%,$(TESTRUNPREFIX)%,$(TESTSPRGS_C))
 TESTSYSRUNS     := $(patsubst \
                      $(TESTNAMEPREFIX)%,$(TESTRUNPREFIX)%,$(TESTSYSPRGS_C))
+REALPATHSRCS_C  := $(wildcard $(TESTNAMEPREFIX)realpath*.c)
+REALPATHRUNS    := $(patsubst \
+                     $(TESTNAMEPREFIX)%.c,$(TESTRUNPREFIX)%,$(REALPATHSRCS_C))
 
 # Tests that are only run manually
 MANTESTDIR       = manual_tests
@@ -455,9 +458,16 @@ $(XTESTNAMEPREFIX)darwin_c_full.o: $(XTESTNAMEPREFIX)darwin_c.c
 $(XTESTNAMEPREFIX)scandir_old.o: $(XTESTNAMEPREFIX)scandir.c
 $(XTESTNAMEPREFIX)scandir_ino32.o: $(XTESTNAMEPREFIX)scandir.c
 
+# The nonstandard realpath tests include the realpath source
+$(TESTNAMEPREFIX)realpath_nonext.o: $(TESTNAMEPREFIX)realpath.c
+$(TESTNAMEPREFIX)realpath_nonposix.o: $(TESTNAMEPREFIX)realpath.c
+
 # Provide a target for all "darwin_c" tests
 $(XTESTRUNPREFIX)darwin_c_all: $(DARWINRUNS)
 
+# Provide a target for all "realpath" tests
+$(TESTRUNPREFIX)realpath_all: $(REALPATHRUNS)
+
 $(MANTESTRUNS): $(MANRUNPREFIX)%: $(MANTESTPREFIX)%
 	$< $(TEST_ARGS)
 
diff --git a/test/test_realpath.c b/test/test_realpath.c
index ad71421..8fcffd2 100644
--- a/test/test_realpath.c
+++ b/test/test_realpath.c
@@ -15,6 +15,13 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+/*
+ * NOTE: Much of the complexity in this test is left over from an earlier
+ * implementation that used a wrapper macro instead of a wrapper function.
+ * Macro-related issues are no longer important to test, though the extra
+ * tests haven't been removed.
+ */
+
 /*
  * Deliberately declaring some potentially redefined names
  * before including the associated header file, to test robustness.
@@ -29,6 +36,7 @@ typedef struct { char *realpath; } rpv_t;
 typedef struct { strfunc_t realpath; } rpf_t;
 
 #include <assert.h>
+#include <libgen.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -88,6 +96,6 @@ main(int argc, char *argv[])
   if (verbose) printf("rpv.realpath = rpf.realpath(path, NULL) supported.\n");
   free((void*)rpv.realpath);
 
-  printf("realpath test succeeded.\n");
+  printf("%s succeeded.\n", basename(argv[0]));
   return 0;
 }
diff --git a/test/test_realpath_nonext.c b/test/test_realpath_nonext.c
new file mode 100644
index 0000000..0305a65
--- /dev/null
+++ b/test/test_realpath_nonext.c
@@ -0,0 +1,7 @@
+/*
+ * Version of test_realpath with Darwin extensions disabled.
+ */
+
+#define _POSIX_C_SOURCE 200112L
+
+#include "test_realpath.c"
diff --git a/test/test_realpath_nonposix.c b/test/test_realpath_nonposix.c
new file mode 100644
index 0000000..9870aac
--- /dev/null
+++ b/test/test_realpath_nonposix.c
@@ -0,0 +1,23 @@
+/*
+ * Version of test_realpath with non-POSIX semantics (32-bit only).
+ */
+
+#if !defined(__LP64__) || !__LP64__
+
+#define _NONSTD_SOURCE
+#include "test_realpath.c"
+
+#else
+
+#include <libgen.h>
+#include <stdio.h>
+
+int
+main(int argc, char *argv[])
+{
+  (void) argc;
+  printf("%s is inapplicable.\n", basename(argv[0]));
+  return 0;
+}
+
+#endif
-- 
GitLab