qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Sean Wei <me@sean.taipei>
To: qemu-devel@nongnu.org
Cc: Sean Wei <me@sean.taipei>
Subject: [PoC] show header-vs-source G_GNUC_PRINTF behavior
Date: Fri, 13 Jun 2025 22:09:50 -0400	[thread overview]
Message-ID: <20250613.qemu.9p.poc@sean.taipei> (raw)
In-Reply-To: <20250613.qemu.9p@sean.taipei>

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


  parent reply	other threads:[~2025-06-14  2:10 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-14  2:07 [PATCH 0/2] virtio-9p: move G_GNUC_PRINTF to header Sean Wei
2025-06-14  2:08 ` [PATCH 1/2] fsdev/9p-marshal: " Sean Wei
2025-06-16  5:10   ` Philippe Mathieu-Daudé
2025-06-14  2:09 ` [PATCH 2/2] hw/9pfs: " Sean Wei
2025-06-16  5:10   ` Philippe Mathieu-Daudé
2025-06-14  2:09 ` Sean Wei [this message]
2025-06-20 14:17 ` [PATCH 0/2] virtio-9p: " Christian Schoenebeck
2025-06-20 15:04   ` Sean Wei

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250613.qemu.9p.poc@sean.taipei \
    --to=me@sean.taipei \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).