Loading...
tests/fprintf.c /dev/null Libc-1669.60.4
--- /dev/null
+++ Libc/Libc-1669.60.4/tests/fprintf.c
@@ -0,0 +1,133 @@
+#include <darwintest.h>
+#include <darwintest_utils.h>
+
+#include "libc_hooks_helper.h"
+#include <xlocale.h>
+
+// Testing fprintf_l instead of fprintf() so we can test locale_tests as well
+T_DECL(libc_hooks_fprintf_l, "Test libc_hooks for fprintf_l")
+{
+    // Setup
+    T_SETUPBEGIN;
+    locale_t loc = duplocale(NULL);
+    FILE *f = fopen("/dev/null", "w");
+    T_SETUPEND;
+
+    // Signed integers (All lengths)
+    int             d = 42;
+    signed char   hhd = 42;
+    short int      hd = 42;
+    long int       ld = 42;
+    long long int lld = 42;
+    intmax_t       jd = 42;
+    size_t         zd = 42;
+    ptrdiff_t      td = 42;
+
+    // Test
+    char fmt_d[] = "%d, %hhd, %hd, %ld, %lld, %jd, %zd, %td";
+    libc_hooks_log_start();
+    fprintf_l(f, loc, fmt_d, d, hhd, hd, ld, lld, jd, zd, td);
+    libc_hooks_log_stop(3);
+
+    // Check
+    T_LOG("fprintf_l(f, loc, \"%s\")", fmt_d);
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, f, sizeof(*f)), "checking f");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read, loc, SIZE_LOCALE_T), "checking loc");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, fmt_d, strlen(fmt_d) + 1), "checking fmt_d");
+
+    // Unsigned integers (All lengths)
+    unsigned int             u = 42;
+    unsigned char          hhu = 42;
+    unsigned short int      hu = 42;
+    unsigned long int       lu = 42;
+    unsigned long long int llu = 42;
+    uintmax_t               ju = 42;
+
+    // Test
+    char fmt_u[] = "%u, %hhu, %hu, %lu, %llu, %ju";
+    libc_hooks_log_start();
+    fprintf_l(f, loc, fmt_u, u, hhu, hu, lu, llu, ju);
+    libc_hooks_log_stop(3);
+
+    // Check
+    T_LOG("fprintf_l(f, loc, \"%s\")", fmt_u);
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, f, sizeof(*f)), "checking f");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read, loc, SIZE_LOCALE_T), "checking loc");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, fmt_u, strlen(fmt_u) + 1), "checking fmt_u");
+
+    // Float points (All length)
+    float       fx = 42.0;
+    double      lf = 42.0;
+    long double LF = 42.0L;
+
+    // Test
+    char fmt_f[] = "%f, %lf, %Lf";
+    libc_hooks_log_start();
+    fprintf_l(f, loc, fmt_f, fx, lf, LF);
+    libc_hooks_log_stop(3);
+
+    // Check
+    T_LOG("fprintf_l(f, loc, \"%s\")", fmt_f);
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, f, sizeof(*f)), "checking f");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read, loc, SIZE_LOCALE_T), "checking loc");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, fmt_f, strlen(fmt_f) + 1), "checking fmt_f");
+
+    // Characters and strings
+    char c = 'C';
+    wchar_t lc = L'W';
+    char s[] = "foo";
+    wchar_t ls[] = L"foo";
+
+    // Test
+    char fmt_s[] = "%c, %lc, %s, %ls";
+    libc_hooks_log_start();
+    fprintf_l(f, loc, fmt_s, c, lc, s, ls);
+    libc_hooks_log_stop(5);
+
+    // Check
+    T_LOG("fprintf_l(f, loc, \"%s\")", fmt_s);
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, f, sizeof(*f)), "checking f");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read, loc, SIZE_LOCALE_T), "checking loc");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, fmt_s, strlen(fmt_s) + 1), "checking fmt_s");
+#if 0 // TBD: Investigate where these are coming from
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, ?, 3), "checking ?");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, ?, 3), "checking ?");
+#endif
+
+    // Special "%n" format specifier (all lengths)
+    int             n;
+    signed char   hhn;
+    short int      hn;
+    long int       ln;
+    long long int lln;
+    intmax_t       jn;
+    size_t         zn;
+    ptrdiff_t      tn;
+
+    // Test
+    char fmt_n[] = "%n, %hhn, %hn, %ln, %lln, %jn, %zn, %tn";
+    libc_hooks_log_start();
+    fprintf_l(f, loc, "%n, %hhn, %hn, %ln, %lln, %jn, %zn, %tn", &n, &hhn, &hn, &ln, &lln, &jn, &zn, &tn);
+    libc_hooks_log_stop(11);
+
+    // Check
+    T_LOG("fprintf_l(f, loc, \"%s\")", fmt_n);
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, f, sizeof(*f)), "checking f");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read, loc, SIZE_LOCALE_T), "checking loc");
+#if 0 // Can't use a non-literal string for %n family for security reasons
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_read_cstring, fmt_n, strlen(fmt_n) + 1), "checking fmt_n");
+#else
+    libc_hooks_log.check++;
+#endif
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &n, sizeof(n)), "checking n");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &hhn, sizeof(hhn)), "checking hhn");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &hn, sizeof(hn)), "checking hn");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &ln, sizeof(ln)), "checking ln");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &lln, sizeof(lln)), "checking lln");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &jn, sizeof(jn)), "checking jn");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &zn, sizeof(zn)), "checking zn");
+    libc_hooks_log_expect(LIBC_HOOKS_LOG(libc_hooks_will_write, &tn, sizeof(tn)), "checking tn");
+
+    // Cleanup
+    fclose(f);
+}