Merge "Wrap sprintf()/snprintf() macros to prevent expansion errors."
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index 23fc944..a13cfea 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -469,7 +469,8 @@
}
#if defined(__clang__)
-#define snprintf(dest, size, ...) __builtin___snprintf_chk(dest, size, 0, __bos(dest), __VA_ARGS__)
+#define __wrap_snprintf(dest, size, ...) __builtin___snprintf_chk(dest, size, 0, __bos(dest), __VA_ARGS__)
+#define snprintf(...) __wrap_snprintf(__VA_ARGS__)
#else
__BIONIC_FORTIFY_INLINE
__printflike(3, 4)
@@ -481,7 +482,8 @@
#endif
#if defined(__clang__)
-#define sprintf(dest, ...) __builtin___sprintf_chk(dest, 0, __bos(dest), __VA_ARGS__)
+#define __wrap_sprintf(dest, ...) __builtin___sprintf_chk(dest, 0, __bos(dest), __VA_ARGS__)
+#define sprintf(...) __wrap_sprintf(__VA_ARGS__)
#else
__BIONIC_FORTIFY_INLINE
__printflike(2, 3)
diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp
index b42c6b7..408991e 100644
--- a/tests/fortify_test.cpp
+++ b/tests/fortify_test.cpp
@@ -825,3 +825,21 @@
ASSERT_EQ('8', buf[8]);
ASSERT_EQ('\0', buf[9]);
}
+
+// Verify that macro expansion is done properly for sprintf/snprintf (which
+// are defined as macros in stdio.h under clang).
+#define CONTENTS "macro expansion"
+#define BUF_AND_SIZE(A) A, sizeof(A)
+#define BUF_AND_CONTENTS(A) A, CONTENTS
+#define BUF_AND_SIZE_AND_CONTENTS(A) A, sizeof(A), CONTENTS
+TEST(TEST_NAME, s_n_printf_macro_expansion) {
+ char buf[BUFSIZ];
+ snprintf(BUF_AND_SIZE(buf), CONTENTS);
+ EXPECT_STREQ(CONTENTS, buf);
+
+ snprintf(BUF_AND_SIZE_AND_CONTENTS(buf));
+ EXPECT_STREQ(CONTENTS, buf);
+
+ sprintf(BUF_AND_CONTENTS(buf));
+ EXPECT_STREQ(CONTENTS, buf);
+}