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);
+}