Blame


1 6509b181 2022-12-30 thomas /*
2 96b8c570 2022-12-30 thomas * Copyright (c) 2022 Omar Polo <op@openbsd.org>
3 6509b181 2022-12-30 thomas *
4 6509b181 2022-12-30 thomas * Permission to use, copy, modify, and distribute this software for any
5 6509b181 2022-12-30 thomas * purpose with or without fee is hereby granted, provided that the above
6 6509b181 2022-12-30 thomas * copyright notice and this permission notice appear in all copies.
7 6509b181 2022-12-30 thomas *
8 6509b181 2022-12-30 thomas * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 6509b181 2022-12-30 thomas * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 6509b181 2022-12-30 thomas * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 6509b181 2022-12-30 thomas * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 6509b181 2022-12-30 thomas * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 6509b181 2022-12-30 thomas * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 6509b181 2022-12-30 thomas * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 6509b181 2022-12-30 thomas */
16 6509b181 2022-12-30 thomas
17 6509b181 2022-12-30 thomas #include <ctype.h>
18 d8bf4f25 2023-09-14 thomas #include <stdarg.h>
19 6509b181 2022-12-30 thomas #include <stdio.h>
20 6509b181 2022-12-30 thomas #include <stdlib.h>
21 d8bf4f25 2023-09-14 thomas #include <string.h>
22 6509b181 2022-12-30 thomas
23 efc1d990 2023-11-25 thomas #include "got_compat.h"
24 6509b181 2022-12-30 thomas #include "tmpl.h"
25 6509b181 2022-12-30 thomas
26 6509b181 2022-12-30 thomas int
27 d8bf4f25 2023-09-14 thomas tp_write(struct template *tp, const char *str, size_t len)
28 d8bf4f25 2023-09-14 thomas {
29 d8bf4f25 2023-09-14 thomas size_t avail;
30 d8bf4f25 2023-09-14 thomas
31 d8bf4f25 2023-09-14 thomas while (len > 0) {
32 d8bf4f25 2023-09-14 thomas avail = tp->tp_cap - tp->tp_len;
33 d8bf4f25 2023-09-14 thomas if (avail == 0) {
34 d8bf4f25 2023-09-14 thomas if (template_flush(tp) == -1)
35 d8bf4f25 2023-09-14 thomas return (-1);
36 d8bf4f25 2023-09-14 thomas avail = tp->tp_cap;
37 d8bf4f25 2023-09-14 thomas }
38 d8bf4f25 2023-09-14 thomas
39 d8bf4f25 2023-09-14 thomas if (len < avail)
40 d8bf4f25 2023-09-14 thomas avail = len;
41 d8bf4f25 2023-09-14 thomas
42 d8bf4f25 2023-09-14 thomas memcpy(tp->tp_buf + tp->tp_len, str, avail);
43 d8bf4f25 2023-09-14 thomas tp->tp_len += avail;
44 d8bf4f25 2023-09-14 thomas str += avail;
45 d8bf4f25 2023-09-14 thomas len -= avail;
46 d8bf4f25 2023-09-14 thomas }
47 d8bf4f25 2023-09-14 thomas
48 d8bf4f25 2023-09-14 thomas return (0);
49 d8bf4f25 2023-09-14 thomas }
50 d8bf4f25 2023-09-14 thomas
51 d8bf4f25 2023-09-14 thomas int
52 d8bf4f25 2023-09-14 thomas tp_writes(struct template *tp, const char *str)
53 d8bf4f25 2023-09-14 thomas {
54 d8bf4f25 2023-09-14 thomas return (tp_write(tp, str, strlen(str)));
55 d8bf4f25 2023-09-14 thomas }
56 d8bf4f25 2023-09-14 thomas
57 d8bf4f25 2023-09-14 thomas int
58 d8bf4f25 2023-09-14 thomas tp_writef(struct template *tp, const char *fmt, ...)
59 d8bf4f25 2023-09-14 thomas {
60 d8bf4f25 2023-09-14 thomas va_list ap;
61 d8bf4f25 2023-09-14 thomas char *str;
62 d8bf4f25 2023-09-14 thomas int r;
63 d8bf4f25 2023-09-14 thomas
64 d8bf4f25 2023-09-14 thomas va_start(ap, fmt);
65 d8bf4f25 2023-09-14 thomas r = vasprintf(&str, fmt, ap);
66 d8bf4f25 2023-09-14 thomas va_end(ap);
67 d8bf4f25 2023-09-14 thomas if (r == -1)
68 d8bf4f25 2023-09-14 thomas return (-1);
69 d8bf4f25 2023-09-14 thomas r = tp_write(tp, str, r);
70 d8bf4f25 2023-09-14 thomas free(str);
71 d8bf4f25 2023-09-14 thomas return (r);
72 d8bf4f25 2023-09-14 thomas }
73 d8bf4f25 2023-09-14 thomas
74 d8bf4f25 2023-09-14 thomas int
75 6509b181 2022-12-30 thomas tp_urlescape(struct template *tp, const char *str)
76 6509b181 2022-12-30 thomas {
77 6509b181 2022-12-30 thomas int r;
78 6509b181 2022-12-30 thomas char tmp[4];
79 6509b181 2022-12-30 thomas
80 6509b181 2022-12-30 thomas if (str == NULL)
81 6509b181 2022-12-30 thomas return (0);
82 6509b181 2022-12-30 thomas
83 6509b181 2022-12-30 thomas for (; *str; ++str) {
84 6509b181 2022-12-30 thomas if (iscntrl((unsigned char)*str) ||
85 6509b181 2022-12-30 thomas isspace((unsigned char)*str) ||
86 6509b181 2022-12-30 thomas *str == '\'' || *str == '"' || *str == '\\') {
87 6509b181 2022-12-30 thomas r = snprintf(tmp, sizeof(tmp), "%%%2X", *str);
88 6509b181 2022-12-30 thomas if (r < 0 || (size_t)r >= sizeof(tmp))
89 6509b181 2022-12-30 thomas return (0);
90 d8bf4f25 2023-09-14 thomas if (tp_write(tp, tmp, r) == -1)
91 6509b181 2022-12-30 thomas return (-1);
92 6509b181 2022-12-30 thomas } else {
93 d8bf4f25 2023-09-14 thomas if (tp_write(tp, str, 1) == -1)
94 6509b181 2022-12-30 thomas return (-1);
95 6509b181 2022-12-30 thomas }
96 6509b181 2022-12-30 thomas }
97 6509b181 2022-12-30 thomas
98 6509b181 2022-12-30 thomas return (0);
99 6509b181 2022-12-30 thomas }
100 6509b181 2022-12-30 thomas
101 6509b181 2022-12-30 thomas int
102 6509b181 2022-12-30 thomas tp_htmlescape(struct template *tp, const char *str)
103 6509b181 2022-12-30 thomas {
104 6509b181 2022-12-30 thomas int r;
105 6509b181 2022-12-30 thomas
106 6509b181 2022-12-30 thomas if (str == NULL)
107 6509b181 2022-12-30 thomas return (0);
108 6509b181 2022-12-30 thomas
109 6509b181 2022-12-30 thomas for (; *str; ++str) {
110 6509b181 2022-12-30 thomas switch (*str) {
111 6509b181 2022-12-30 thomas case '<':
112 d8bf4f25 2023-09-14 thomas r = tp_write(tp, "&lt;", 4);
113 6509b181 2022-12-30 thomas break;
114 6509b181 2022-12-30 thomas case '>':
115 d8bf4f25 2023-09-14 thomas r = tp_write(tp, "&gt;", 4);
116 6509b181 2022-12-30 thomas break;
117 6509b181 2022-12-30 thomas case '&':
118 d8bf4f25 2023-09-14 thomas r = tp_write(tp, "&amp;", 5);
119 6509b181 2022-12-30 thomas break;
120 6509b181 2022-12-30 thomas case '"':
121 d8bf4f25 2023-09-14 thomas r = tp_write(tp, "&quot;", 6);
122 6509b181 2022-12-30 thomas break;
123 6509b181 2022-12-30 thomas case '\'':
124 d8bf4f25 2023-09-14 thomas r = tp_write(tp, "&apos;", 6);
125 6509b181 2022-12-30 thomas break;
126 6509b181 2022-12-30 thomas default:
127 d8bf4f25 2023-09-14 thomas r = tp_write(tp, str, 1);
128 6509b181 2022-12-30 thomas break;
129 6509b181 2022-12-30 thomas }
130 6509b181 2022-12-30 thomas
131 6509b181 2022-12-30 thomas if (r == -1)
132 6509b181 2022-12-30 thomas return (-1);
133 6509b181 2022-12-30 thomas }
134 6509b181 2022-12-30 thomas
135 6509b181 2022-12-30 thomas return (0);
136 6509b181 2022-12-30 thomas }
137 6509b181 2022-12-30 thomas
138 6509b181 2022-12-30 thomas struct template *
139 d8bf4f25 2023-09-14 thomas template(void *arg, tmpl_write writefn, char *buf, size_t siz)
140 6509b181 2022-12-30 thomas {
141 6509b181 2022-12-30 thomas struct template *tp;
142 6509b181 2022-12-30 thomas
143 6509b181 2022-12-30 thomas if ((tp = calloc(1, sizeof(*tp))) == NULL)
144 6509b181 2022-12-30 thomas return (NULL);
145 6509b181 2022-12-30 thomas
146 6509b181 2022-12-30 thomas tp->tp_arg = arg;
147 d8bf4f25 2023-09-14 thomas tp->tp_write = writefn;
148 d8bf4f25 2023-09-14 thomas tp->tp_buf = buf;
149 d8bf4f25 2023-09-14 thomas tp->tp_cap = siz;
150 6509b181 2022-12-30 thomas
151 6509b181 2022-12-30 thomas return (tp);
152 6509b181 2022-12-30 thomas }
153 6509b181 2022-12-30 thomas
154 d8bf4f25 2023-09-14 thomas int
155 d8bf4f25 2023-09-14 thomas template_flush(struct template *tp)
156 d8bf4f25 2023-09-14 thomas {
157 d8bf4f25 2023-09-14 thomas if (tp->tp_len == 0)
158 d8bf4f25 2023-09-14 thomas return (0);
159 d8bf4f25 2023-09-14 thomas
160 d8bf4f25 2023-09-14 thomas if (tp->tp_write(tp->tp_arg, tp->tp_buf, tp->tp_len) == -1)
161 d8bf4f25 2023-09-14 thomas return (-1);
162 d8bf4f25 2023-09-14 thomas tp->tp_len = 0;
163 d8bf4f25 2023-09-14 thomas return (0);
164 d8bf4f25 2023-09-14 thomas }
165 d8bf4f25 2023-09-14 thomas
166 6509b181 2022-12-30 thomas void
167 6509b181 2022-12-30 thomas template_free(struct template *tp)
168 6509b181 2022-12-30 thomas {
169 6509b181 2022-12-30 thomas free(tp->tp_tmp);
170 6509b181 2022-12-30 thomas free(tp);
171 6509b181 2022-12-30 thomas }