varnish-cache/lib/libvarnish/vsb.c
1
/*-
2
 * Copyright (c) 2000-2008 Poul-Henning Kamp
3
 * Copyright (c) 2000-2008 Dag-Erling Coïdan Smørgrav
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer
11
 *    in this position and unchanged.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 * SUCH DAMAGE.
27
__FBSDID("$FreeBSD: head/sys/kern/subr_vsb.c 222004 2011-05-17 06:36:32Z phk $")
28
 */
29
30
#include "config.h"
31
32
#include <ctype.h>
33
#include <errno.h>
34
#include <stdarg.h>
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <string.h>
38
39
#include "vdef.h"
40
#include "vas.h"        // XXX Flexelint "not used" - but req'ed for assert()
41
#include "vsb.h"
42
43
#define KASSERT(e, m)           assert(e)
44
#define SBMALLOC(size)          malloc(size)
45
#define SBFREE(buf)             free(buf)
46
47
#define roundup2(x, y)  (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
48
49
/*
50
 * Predicates
51
 */
52
#define VSB_ISDYNAMIC(s)        ((s)->s_flags & VSB_DYNAMIC)
53
#define VSB_ISDYNSTRUCT(s)      ((s)->s_flags & VSB_DYNSTRUCT)
54
#define VSB_HASROOM(s)          ((s)->s_len < (s)->s_size - 1)
55
#define VSB_FREESPACE(s)        ((s)->s_size - ((s)->s_len + 1))
56
#define VSB_CANEXTEND(s)        ((s)->s_flags & VSB_AUTOEXTEND)
57
58
/*
59
 * Set / clear flags
60
 */
61
#define VSB_SETFLAG(s, f)       do { (s)->s_flags |= (f); } while (0)
62
#define VSB_CLEARFLAG(s, f)     do { (s)->s_flags &= ~(f); } while (0)
63
64
#define VSB_MINEXTENDSIZE       16              /* Should be power of 2. */
65
66
#ifdef PAGE_SIZE
67
#define VSB_MAXEXTENDSIZE       PAGE_SIZE
68
#define VSB_MAXEXTENDINCR       PAGE_SIZE
69
#else
70
#define VSB_MAXEXTENDSIZE       4096
71
#define VSB_MAXEXTENDINCR       4096
72
#endif
73
74
/*
75
 * Debugging support
76
 */
77
#if !defined(NDEBUG)
78
static void
79 94783242
_assert_VSB_integrity(const char *fun, const struct vsb *s)
80
{
81
82
        (void)fun;
83
        (void)s;
84 94783242
        KASSERT(s != NULL,
85
            ("%s called with a NULL vsb pointer", fun));
86 94783242
        KASSERT(s->magic == VSB_MAGIC,
87
            ("%s called wih an bogus vsb pointer", fun));
88 94783242
        KASSERT(s->s_buf != NULL,
89
            ("%s called with uninitialized or corrupt vsb", fun));
90 94783242
        KASSERT(s->s_len < s->s_size,
91
            ("wrote past end of vsb (%d >= %d)", s->s_len, s->s_size));
92 94783242
}
93
94
static void
95 92824278
_assert_VSB_state(const char *fun, const struct vsb *s, int state)
96
{
97
98
        (void)fun;
99
        (void)s;
100
        (void)state;
101 92824278
        KASSERT((s->s_flags & VSB_FINISHED) == state,
102
            ("%s called with %sfinished or corrupt vsb", fun,
103
            (state ? "un" : "")));
104 92824278
}
105
#define assert_VSB_integrity(s) _assert_VSB_integrity(__func__, (s))
106
#define assert_VSB_state(s, i)   _assert_VSB_state(__func__, (s), (i))
107
#else
108
#define assert_VSB_integrity(s) do { } while (0)
109
#define assert_VSB_state(s, i)   do { } while (0)
110
#endif
111
112
#ifdef CTASSERT
113
CTASSERT(powerof2(VSB_MAXEXTENDSIZE));
114
CTASSERT(powerof2(VSB_MAXEXTENDINCR));
115
#endif
116
117
static int
118 942209
VSB_extendsize(int size)
119
{
120
        int newsize;
121
122 942209
        if (size < (int)VSB_MAXEXTENDSIZE) {
123 923940
                newsize = VSB_MINEXTENDSIZE;
124 3130163
                while (newsize < size)
125 1282283
                        newsize *= 2;
126
        } else {
127 18269
                newsize = roundup2(size, VSB_MAXEXTENDINCR);
128
        }
129 942209
        KASSERT(newsize >= size, ("%s: %d < %d\n", __func__, newsize, size));
130 942209
        return (newsize);
131
}
132
133
/*
134
 * Extend an vsb.
135
 */
136
static int
137 553875
VSB_extend(struct vsb *s, int addlen)
138
{
139
        char *newbuf;
140
        int newsize;
141
142 553875
        if (!VSB_CANEXTEND(s))
143 0
                return (-1);
144 553875
        newsize = VSB_extendsize(s->s_size + addlen);
145 553875
        if (VSB_ISDYNAMIC(s))
146 553875
                newbuf = realloc(s->s_buf, newsize);
147
        else
148 0
                newbuf = SBMALLOC(newsize);
149 553875
        if (newbuf == NULL)
150 0
                return (-1);
151 553875
        if (!VSB_ISDYNAMIC(s)) {
152 0
                memcpy(newbuf, s->s_buf, s->s_size);
153 0
                VSB_SETFLAG(s, VSB_DYNAMIC);
154
        }
155 553875
        s->s_buf = newbuf;
156 553875
        s->s_size = newsize;
157 553875
        return (0);
158
}
159
160
static void
161 89456995
_vsb_indent(struct vsb *s)
162
{
163 89457569
        if (s->s_indent == 0 || s->s_error != 0 ||
164 1148
            (s->s_len > 0 && s->s_buf[s->s_len - 1] != '\n'))
165 89456613
                return;
166 382
        if (VSB_FREESPACE(s) <= s->s_indent &&
167 0
            VSB_extend(s, s->s_indent) < 0) {
168 0
                s->s_error = ENOMEM;
169 0
                return;
170
        }
171 382
        memset(s->s_buf + s->s_len, ' ', s->s_indent);
172 382
        s->s_len += s->s_indent;
173
}
174
175
/*
176
 * Initialize the internals of an vsb.
177
 * If buf is non-NULL, it points to a static or already-allocated string
178
 * big enough to hold at least length characters.
179
 */
180
static struct vsb *
181 388953
VSB_newbuf(struct vsb *s, char *buf, int length, int flags)
182
{
183
184 388953
        memset(s, 0, sizeof(*s));
185 388953
        s->magic = VSB_MAGIC;
186 388953
        s->s_flags = flags;
187 388953
        s->s_size = length;
188 388953
        s->s_buf = buf;
189
190 388953
        if ((s->s_flags & VSB_AUTOEXTEND) == 0) {
191 618
                KASSERT(s->s_size > 1,
192
                    ("attempt to create a too small vsb"));
193
        }
194
195 388953
        if (s->s_buf != NULL)
196 618
                return (s);
197
198 388335
        if ((flags & VSB_AUTOEXTEND) != 0)
199 388333
                s->s_size = VSB_extendsize(s->s_size);
200
201 388340
        s->s_buf = SBMALLOC(s->s_size);
202 388340
        if (s->s_buf == NULL)
203 0
                return (NULL);
204 388340
        VSB_SETFLAG(s, VSB_DYNAMIC);
205 388340
        return (s);
206
}
207
208
/*
209
 * Initialize an vsb.
210
 * If buf is non-NULL, it points to a static or already-allocated string
211
 * big enough to hold at least length characters.
212
 */
213
struct vsb *
214 388957
VSB_new(struct vsb *s, char *buf, int length, int flags)
215
{
216
217 388957
        KASSERT(length >= 0,
218
            ("attempt to create an vsb of negative length (%d)", length));
219 388957
        KASSERT((flags & ~VSB_USRFLAGMSK) == 0,
220
            ("%s called with invalid flags", __func__));
221
222 388957
        flags &= VSB_USRFLAGMSK;
223 388957
        if (s != NULL)
224 618
                return (VSB_newbuf(s, buf, length, flags));
225
226 388339
        s = SBMALLOC(sizeof(*s));
227 388339
        if (s == NULL)
228 0
                return (NULL);
229 388339
        if (VSB_newbuf(s, buf, length, flags) == NULL) {
230 0
                SBFREE(s);
231 0
                return (NULL);
232
        }
233 388341
        VSB_SETFLAG(s, VSB_DYNSTRUCT);
234 388341
        return (s);
235
}
236
237
/*
238
 * Clear an vsb and reset its position.
239
 */
240
void
241 1061521
VSB_clear(struct vsb *s)
242
{
243
244 1061521
        assert_VSB_integrity(s);
245
        /* don't care if it's finished or not */
246
247 1061482
        VSB_CLEARFLAG(s, VSB_FINISHED);
248 1061482
        s->s_error = 0;
249 1061482
        s->s_len = 0;
250 1061482
        s->s_indent = 0;
251 1061482
}
252
253
/*
254
 * Append a byte to an vsb.  This is the core function for appending
255
 * to an vsb and is the main place that deals with extending the
256
 * buffer and marking overflow.
257
 */
258
static void
259 86664347
VSB_put_byte(struct vsb *s, int c)
260
{
261
262 86664347
        assert_VSB_integrity(s);
263 86664193
        assert_VSB_state(s, 0);
264
265 86664228
        if (s->s_error != 0)
266 0
                return;
267 86664228
        _vsb_indent(s);
268 86664066
        if (VSB_FREESPACE(s) <= 0) {
269 346530
                if (VSB_extend(s, 1) < 0)
270 0
                        s->s_error = ENOMEM;
271 346530
                if (s->s_error != 0)
272 0
                        return;
273
        }
274 86664066
        s->s_buf[s->s_len++] = (char)c;
275
}
276
277
/*
278
 * Append a byte string to an vsb.
279
 */
280
int
281 36093
VSB_bcat(struct vsb *s, const void *buf, ssize_t len)
282
{
283 36093
        assert_VSB_integrity(s);
284 36093
        assert_VSB_state(s, 0);
285
286 36093
        assert(len >= 0);
287 36093
        if (s->s_error != 0)
288 0
                return (-1);
289 36093
        if (len == 0)
290 2470
                return (0);
291 33623
        _vsb_indent(s);
292 33623
        if (len > VSB_FREESPACE(s)) {
293 6942
                if (VSB_extend(s, len - VSB_FREESPACE(s)) < 0)
294 0
                        s->s_error = ENOMEM;
295 6942
                if (s->s_error != 0)
296 0
                        return (-1);
297
        }
298 33623
        memcpy(s->s_buf + s->s_len, buf, len);
299 33623
        s->s_len += len;
300 33623
        return (0);
301
}
302
303
/*
304
 * Append a string to an vsb.
305
 */
306
int
307 1333655
VSB_cat(struct vsb *s, const char *str)
308
{
309
310 1333655
        assert_VSB_integrity(s);
311 1333647
        assert_VSB_state(s, 0);
312
313 1333716
        if (s->s_error != 0)
314 0
                return (-1);
315
316 76504131
        while (*str != '\0') {
317 73836767
                VSB_put_byte(s, *str++);
318 73836699
                if (s->s_error != 0)
319 0
                        return (-1);
320
        }
321 1333648
        return (0);
322
}
323
324
/*
325
 * Format the given argument list and append the resulting string to an vsb.
326
 */
327
int
328 2760486
VSB_vprintf(struct vsb *s, const char *fmt, va_list ap)
329
{
330
        va_list ap_copy;
331
        int len;
332
333 2760486
        assert_VSB_integrity(s);
334 2760450
        assert_VSB_state(s, 0);
335
336 2760449
        KASSERT(fmt != NULL,
337
            ("%s called with a NULL format string", __func__));
338
339 2760449
        if (s->s_error != 0)
340 0
                return (-1);
341 2760449
        _vsb_indent(s);
342
343
        /*
344
         * For the moment, there is no way to get vsnprintf(3) to hand
345
         * back a character at a time, to push everything into
346
         * VSB_putc_func() as was done for the kernel.
347
         *
348
         * In userspace, while drains are useful, there's generally
349
         * not a problem attempting to malloc(3) on out of space.  So
350
         * expand a userland vsb if there is not enough room for the
351
         * data produced by VSB_[v]printf(3).
352
         */
353
354
        do {
355 2960929
                va_copy(ap_copy, ap);
356 2960929
                len = vsnprintf(&s->s_buf[s->s_len], VSB_FREESPACE(s) + 1,
357
                    fmt, ap_copy);
358 2960929
                va_end(ap_copy);
359 2960929
                if (len < 0) {
360 0
                        s->s_error = errno;
361 0
                        return (-1);
362
                }
363 3161332
        } while (len > VSB_FREESPACE(s) &&
364 2960929
            VSB_extend(s, len - VSB_FREESPACE(s)) == 0);
365
366
        /*
367
         * s->s_len is the length of the string, without the terminating nul.
368
         * When updating s->s_len, we must subtract 1 from the length that
369
         * we passed into vsnprintf() because that length includes the
370
         * terminating nul.
371
         *
372
         * vsnprintf() returns the amount that would have been copied,
373
         * given sufficient space, so don't over-increment s_len.
374
         */
375 2760512
        if (VSB_FREESPACE(s) < len)
376 0
                len = VSB_FREESPACE(s);
377 2760512
        s->s_len += len;
378 2760512
        if (!VSB_HASROOM(s) && !VSB_CANEXTEND(s))
379 0
                s->s_error = ENOMEM;
380
381 2760512
        KASSERT(s->s_len < s->s_size,
382
            ("wrote past end of vsb (%d >= %d)", s->s_len, s->s_size));
383
384 2760512
        if (s->s_error != 0)
385 0
                return (-1);
386 2760512
        return (0);
387
}
388
389
/*
390
 * Format the given arguments and append the resulting string to an vsb.
391
 */
392
int
393 1372207
VSB_printf(struct vsb *s, const char *fmt, ...)
394
{
395
        va_list ap;
396
        int result;
397
398 1372207
        va_start(ap, fmt);
399 1372207
        result = VSB_vprintf(s, fmt, ap);
400 1372226
        va_end(ap);
401 1372226
        return (result);
402
}
403
404
/*
405
 * Append a character to an vsb.
406
 */
407
int
408 12831365
VSB_putc(struct vsb *s, int c)
409
{
410
411 12831365
        VSB_put_byte(s, c);
412 12831147
        if (s->s_error != 0)
413 0
                return (-1);
414 12831147
        return (0);
415
}
416
417
/*
418
 * Check if an vsb has an error.
419
 */
420
int
421 104
VSB_error(const struct vsb *s)
422
{
423
424 104
        return (s->s_error);
425
}
426
427
/*
428
 * Finish off an vsb.
429
 */
430
int
431 1019999
VSB_finish(struct vsb *s)
432
{
433
434 1019999
        assert_VSB_integrity(s);
435 1019991
        assert_VSB_state(s, 0);
436
437 1019994
        s->s_buf[s->s_len] = '\0';
438 1019994
        VSB_SETFLAG(s, VSB_FINISHED);
439 1019994
        errno = s->s_error;
440 1019997
        if (s->s_error)
441 0
                return (-1);
442 1019997
        return (0);
443
}
444
445
/*
446
 * Return a pointer to the vsb data.
447
 */
448
char *
449 1012757
VSB_data(const struct vsb *s)
450
{
451
452 1012757
        assert_VSB_integrity(s);
453 1012756
        assert_VSB_state(s, VSB_FINISHED);
454
455 1012751
        return (s->s_buf);
456
}
457
458
/*
459
 * Return the length of the vsb data.
460
 */
461
ssize_t
462 530842
VSB_len(const struct vsb *s)
463
{
464
465 530842
        assert_VSB_integrity(s);
466
        /* don't care if it's finished or not */
467
468 530839
        if (s->s_error != 0)
469 0
                return (-1);
470 530839
        return (s->s_len);
471
}
472
473
/*
474
 * Clear an vsb, free its buffer if necessary.
475
 */
476
void
477 367763
VSB_delete(struct vsb *s)
478
{
479
        int isdyn;
480
481 367763
        assert_VSB_integrity(s);
482
        /* don't care if it's finished or not */
483
484 367762
        if (VSB_ISDYNAMIC(s))
485 367761
                SBFREE(s->s_buf);
486 367762
        isdyn = VSB_ISDYNSTRUCT(s);
487 367762
        memset(s, 0, sizeof(*s));
488 367762
        if (isdyn)
489 367763
                SBFREE(s);
490 367762
}
491
492
void
493 342533
VSB_destroy(struct vsb **s)
494
{
495 342533
        VSB_delete(*s);
496 342532
        *s = NULL;
497 342532
}
498
499
/*
500
 * Quote a string
501
 */
502
void
503 103815
VSB_quote_pfx(struct vsb *s, const char *pfx, const void *v, int len, int how)
504
{
505
        const char *p;
506
        const char *q;
507 103815
        int quote = 0;
508 103815
        int nl = 0;
509
        const unsigned char *u, *w;
510
511 103815
        assert(v != NULL);
512 103815
        if (len == -1)
513 36811
                len = strlen(v);
514
515 103815
        if (len == 0 && (how & VSB_QUOTE_CSTR)) {
516 138
                VSB_printf(s, "%s\"\"", pfx);
517 138
                return;
518 103677
        } else if (len == 0)
519 3692
                return;
520
521 99985
        VSB_cat(s, pfx);
522
523 99980
        if (how & VSB_QUOTE_HEX) {
524 532
                u = v;
525 1593
                for (w = u; w < u + len; w++)
526 1358
                        if (*w != 0x00)
527 297
                                break;
528 532
                VSB_printf(s, "0x");
529 532
                if (w == u + len && len > 4) {
530 13
                        VSB_printf(s, "0...0");
531
                } else {
532 4069
                        for (w = u; w < u + len; w++)
533 3550
                                VSB_printf(s, "%02x", *w);
534
                }
535 532
                return;
536
        }
537 99448
        p = v;
538
539 1145396
        for (q = p; q < p + len; q++) {
540 1104928
                if (!isgraph(*q) || *q == '"' || *q == '\\') {
541 58985
                        quote++;
542 58985
                        break;
543
                }
544
        }
545 99453
        if (!quote && !(how & (VSB_QUOTE_JSON|VSB_QUOTE_CSTR))) {
546 21414
                (void)VSB_bcat(s, p, len);
547 21414
                if ((how & (VSB_QUOTE_UNSAFE|VSB_QUOTE_NONL))
548 14892
                    && p[len-1] != '\n')
549 14892
                        (void)VSB_putc(s, '\n');
550 21414
                return;
551
        }
552
553 78039
        if (how & VSB_QUOTE_CSTR)
554 33071
                (void)VSB_putc(s, '"');
555
556 8561969
        for (q = p; q < p + len; q++) {
557 8483930
                if (nl)
558 74256
                        VSB_cat(s, pfx);
559 8484211
                nl = 0;
560 8484211
                switch (*q) {
561
                case '?':
562 5748
                        if (how & VSB_QUOTE_CSTR)
563 14
                                (void)VSB_putc(s, '\\');
564 5748
                        (void)VSB_putc(s, *q);
565 5443
                        break;
566
                case ' ':
567 1230019
                        (void)VSB_putc(s, *q);
568 1230020
                        break;
569
                case '\\':
570
                case '"':
571 80918
                        if (!(how & VSB_QUOTE_UNSAFE))
572 60425
                                (void)VSB_putc(s, '\\');
573 80918
                        (void)VSB_putc(s, *q);
574 80918
                        break;
575
                case '\n':
576 270819
                        if (how & VSB_QUOTE_CSTR) {
577 178923
                                (void)VSB_printf(s, "\\n\"\n%s\t\"", pfx);
578 91896
                        } else if (how & (VSB_QUOTE_NONL|VSB_QUOTE_UNSAFE)) {
579 91895
                                (void)VSB_printf(s, "\n");
580 91897
                                nl = 1;
581
                        } else {
582 1
                                (void)VSB_printf(s, "\\n");
583
                        }
584 270821
                        break;
585
                case '\r':
586 35334
                        (void)VSB_cat(s, "\\r");
587 35334
                        break;
588
                case '\t':
589 39346
                        (void)VSB_cat(s, "\\t");
590 39346
                        break;
591
                default:
592
                        /* XXX: Implement VSB_QUOTE_JSON */
593 6822027
                        if (isgraph(*q))
594 6816418
                                (void)VSB_putc(s, *q);
595
                        else
596 5778
                                (void)VSB_printf(s, "\\%o", *q & 0xff);
597 6822029
                        break;
598
                }
599
        }
600 78039
        if (how & VSB_QUOTE_CSTR)
601 33071
                (void)VSB_putc(s, '"');
602 78039
        if ((how & (VSB_QUOTE_NONL|VSB_QUOTE_UNSAFE)) && !nl)
603 25973
                (void)VSB_putc(s, '\n');
604
}
605
606
void
607 41649
VSB_quote(struct vsb *s, const void *v, int len, int how)
608
{
609 41649
        VSB_quote_pfx(s, "", v, len, how);
610 41649
}
611
612
/*
613
 * Indentation
614
 */
615
616
void
617 144
VSB_indent(struct vsb * s, int i)
618
{
619
620 144
        assert_VSB_integrity(s);
621 144
        if (s->s_indent + i < 0)
622 0
                s->s_error = EINVAL;
623
        else
624 144
                s->s_indent += i;
625 144
}