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
next prev 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).