Skip to content

Instantly share code, notes, and snippets.

@citizen428
Created February 26, 2026 18:10
Show Gist options
  • Select an option

  • Save citizen428/2803ea2751282abb622d94ce77636569 to your computer and use it in GitHub Desktop.

Select an option

Save citizen428/2803ea2751282abb622d94ce77636569 to your computer and use it in GitHub Desktop.
C preprocessor abuse
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "abuse.h"
// clang-format off
#define WATER_CSS "https://cdn.jsdelivr.net/npm/water.css@2/out/water.css"
#define HTML \
head( \
tag(title, C Preprocessor Abuse) \
link(_(rel="stylesheet" href=WATER_CSS)) \
) \
body( \
div(attr(class, "container"), \
h1(, C Preprocessor Abuse) \
hr \
p(, This page was generated entirely by the C preprocessor.) \
p(, HTML tags are defined as function-like macros that expand to \
angle-bracket syntax. The entire page is a single string \
literal assembled at compile time via token stringification.) \
tag(blockquote, tag(em, The compiler is the template engine.)) \
hr \
) \
)
// clang-format on
int main(void) {
char *response = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"\r\n" html(HTML);
int fd = socket(AF_INET, SOCK_STREAM, 0);
int opt = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(8080),
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
};
bind(fd, (struct sockaddr *)&addr, sizeof(addr));
listen(fd, 1);
puts("Listening on http://localhost:8080");
while (true) {
int client = accept(fd, NULL, NULL);
char buf[1024];
read(client, buf, sizeof(buf));
write(client, response, strlen(response));
close(client);
}
}
#define _(...) __VA_ARGS__
#define html_(x) "<html>" #x "</html>"
#define html(x) html_(x)
#define tag(name, x) <name>x</name>
#define tag_attr(name, attrs, x) <name attrs>x</name>
#define tag_void(name, attrs) <name attrs>
#define attr(name, value) name = value
#define head(x) tag(head, x)
#define link(attrs) tag_void(link, attrs)
#define body(x) tag(body, x)
#define div(attrs, x) tag_attr(div, attrs, x)
#define h1(attrs, x) tag_attr(h1, attrs, x)
#define hr <hr />
#define p(attrs, x) tag_attr(p, attrs, x)
CC ?= clang
CFLAGS = -std=c23 -Wall -Werror
run: clean abuse
@./abuse
abuse:
@$(CC) $(CFLAGS) -I. -o abuse abuse.c
clean:
@rm -f ./abuse
.PHONY: clean run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment