This patch is NOT meant for merge.
Just a simple proof-of-concept so reviewers can quickly reproduce
the difference between placing a G_GNUC_PRINTF attribute in *.c versus
*.h file.

What it tests
-------------

* Two identical printf-style helpers (my_printf) are provided:
  - v1: attribute lives in foo-v1.c
  - v2: attribute lives in foo-v2.h
* Two callers (bar-v1.c, bar-v2.c) intentionally pass too few
  arguments: `my_printf("%d %d %d\n", 1)`.
* A trivial Makefile builds each variant and shows whether GCC emits
  the missing-argument warning.

Expected result
---------------

$ make -C poc run
// Compiling version 1 (Place G_GNUC_PRINTF in 'foo-v1.c')
No warning will appear, sliently cause security flaw

// Compiling version 2 (Place G_GNUC_PRINTF in 'foo-v2.h')
bar-v2.c:4:17: warning: more '%' conversions than data arguments 
[-Wformat-insufficient-args]



Signed-off-by: Sean Wei <me@sean.taipei>
---
 poc/foo-v1.h  |  3 +++
 poc/foo-v1.c  | 10 ++++++++++
 poc/bar-v1.c  |  6 ++++++
 poc/foo-v2.h  |  3 +++
 poc/foo-v2.c  | 10 ++++++++++
 poc/bar-v2.c  |  6 ++++++
 poc/Makefile  | 39 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 77 insertions(+)
 create mode 100644 poc/foo-v1.h
 create mode 100644 poc/foo-v1.c
 create mode 100644 poc/bar-v1.c
 create mode 100644 poc/foo-v2.h
 create mode 100644 poc/foo-v2.c
 create mode 100644 poc/bar-v2.c
 create mode 100644 poc/Makefile

diff --git a/poc/foo-v1.h b/poc/foo-v1.h
new file mode 100644
index 0000000000..37b5403ba6
--- /dev/null
+++ b/poc/foo-v1.h
@@ -0,0 +1,3 @@
+#define G_GNUC_PRINTF(n, m) __attribute__((format(printf, n, m)))
+
+void my_printf(const char *fmt, ...);
diff --git a/poc/foo-v1.c b/poc/foo-v1.c
new file mode 100644
index 0000000000..ce89f95e3e
--- /dev/null
+++ b/poc/foo-v1.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include "foo-v2.h"
+
+void G_GNUC_PRINTF(1, 2) my_printf(const char *fmt, ...) {
+       va_list ap;
+       va_start(ap, fmt);
+       vprintf(fmt, ap);
+       va_end(ap);
+}
diff --git a/poc/bar-v1.c b/poc/bar-v1.c
new file mode 100644
index 0000000000..6e707e13b4
--- /dev/null
+++ b/poc/bar-v1.c
@@ -0,0 +1,6 @@
+#include "foo-v1.h"
+
+int main() {
+       my_printf("%d %d %d\n", 1);  // missing arguments
+       return 0;
+}
diff --git a/poc/foo-v2.h b/poc/foo-v2.h
new file mode 100644
index 0000000000..8bb56d3181
--- /dev/null
+++ b/poc/foo-v2.h
@@ -0,0 +1,3 @@
+#define G_GNUC_PRINTF(n, m) __attribute__((format(printf, n, m)))
+
+void G_GNUC_PRINTF(1, 2) my_printf(const char *fmt, ...);
diff --git a/poc/foo-v2.c b/poc/foo-v2.c
new file mode 100644
index 0000000000..3f18632ee6
--- /dev/null
+++ b/poc/foo-v2.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include "foo-v1.h"
+
+void my_printf(const char *fmt, ...) {
+       va_list ap;
+       va_start(ap, fmt);
+       vprintf(fmt, ap);
+       va_end(ap);
+}
diff --git a/poc/bar-v2.c b/poc/bar-v2.c
new file mode 100644
index 0000000000..e06fd87056
--- /dev/null
+++ b/poc/bar-v2.c
@@ -0,0 +1,6 @@
+#include "foo-v2.h"
+
+int main() {
+       my_printf("%d %d %d\n", 1);  // missing arguments
+       return 0;
+}
diff --git a/poc/Makefile b/poc/Makefile
new file mode 100644
index 0000000000..5725c9ff63
--- /dev/null
+++ b/poc/Makefile
@@ -0,0 +1,39 @@
+CC ?= gcc
+CFLAGS ?= -Wall
+
+TARGET = prog-v1 prog-v2
+SRCS   = foo-v1.c foo-v2.c bar-v1.c bar-v2.c
+OBJS   = $(SRCS:.c=.o)
+
+.PHONY: run
+
+run: clean prog-v1 prog-v2
+
+
+prog-v1:
+       @echo
+       @echo
+       @echo "### Compiling version 1 ###"
+       @echo "Place G_GNUC_PRINTF in 'foo.c' only"
+       @echo "No warning will appear, sliently cause security flaw"
+       @echo
+       $(CC) $(CFLAGS) -c foo-v1.c -o foo-v1.o
+       $(CC) $(CFLAGS) -c bar-v1.c -o bar-v1.o
+       @echo
+       $(CC) foo-v1.o bar-v1.o -o $@
+
+prog-v2:
+       @echo
+       @echo
+       @echo "### Compiling version 2###"
+       @echo "Place G_GNUC_PRINTF in 'foo.h' instead"
+       @echo "Show warning for missing arguments"
+       @echo
+       $(CC) $(CFLAGS) -c foo-v2.c -o foo-v2.o
+       $(CC) $(CFLAGS) -c bar-v2.c -o bar-v2.o
+       @echo
+       $(CC) foo-v2.o bar-v2.o -o $@
+
+clean:
+       @echo "### Clean all artifacts ###"
+       rm -f $(TARGET) $(OBJS)
-- 
2.49.0

Reply via email to