summary refs log tree commit diff
path: root/template.c
diff options
context:
space:
mode:
Diffstat (limited to 'template.c')
-rw-r--r--template.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/template.c b/template.c
index 3caa8b2..92c6381 100644
--- a/template.c
+++ b/template.c
@@ -24,6 +24,48 @@
 
 #include "archive.h"
 
+int escapeURL(FILE *file, const char *str) {
+	static const char *Safe = {
+		"$-_.+!*'(),"
+		"0123456789"
+		"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+		"abcdefghijklmnopqrstuvwxyz"
+	};
+	while (*str) {
+		size_t len = strspn(str, Safe);
+		if (len) {
+			size_t n = fwrite(str, len, 1, file);
+			if (!n) return -1;
+		}
+		str += len;
+		if (*str) {
+			int n = fprintf(file, "%%%02X", *str++);
+			if (n < 0) return n;
+		}
+	}
+	return 0;
+}
+
+int escapeXML(FILE *file, const char *str) {
+	while (*str) {
+		int n = 0;
+		switch (*str) {
+			break; case '"': n = fprintf(file, "&quot;"); str++;
+			break; case '&': n = fprintf(file, "&amp;"); str++;
+			break; case '<': n = fprintf(file, "&lt;"); str++;
+			break; case '>': n = fprintf(file, "&gt;"); str++;
+		}
+		if (n < 0) return n;
+		size_t len = strcspn(str, "\"&<>");
+		if (len) {
+			size_t n = fwrite(str, len, 1, file);
+			if (!n) return -1;
+		}
+		str += len;
+	}
+	return 0;
+}
+
 int templateRender(
 	FILE *file, const char *template,
 	const struct Variable *vars, EscapeFn *escape
@@ -46,7 +88,7 @@ int templateRender(
 			}
 			int error = escape(file, value);
 			if (error) return error;
-		} else {
+		} else if (len) {
 			size_t n = fwrite(template, len, 1, file);
 			if (!n) return -1;
 		}