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 - 1L)
55
#define VSB_FREESPACE(s)        ((s)->s_size - ((s)->s_len + 1L))
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 248153214
_assert_VSB_integrity(const char *fun, const struct vsb *s)
80
{
81
82
        (void)fun;
83
        (void)s;
84 248153214
        KASSERT(s != NULL,
85
            ("%s called with a NULL vsb pointer", fun));
86 248153214
        KASSERT(s->magic == VSB_MAGIC,
87
            ("%s called wih an bogus vsb pointer", fun));
88 248153214
        KASSERT(s->s_buf != NULL,
89
            ("%s called with uninitialized or corrupt vsb", fun));
90 248153214
        KASSERT(s->s_len < s->s_size,
91
            ("wrote past end of vsb (%d >= %d)", s->s_len, s->s_size));
92 248153214
}
93
94
static void
95 243333085
_assert_VSB_state(const char *fun, const struct vsb *s, int state)
96
{
97
98
        (void)fun;
99
        (void)s;
100
        (void)state;
101 243333085
        KASSERT((s->s_flags & VSB_FINISHED) == state,
102
            ("%s called with %sfinished or corrupt vsb", fun,
103
            (state ? "un" : "")));
104 243333085
}
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 ssize_t
118 2340929
VSB_extendsize(ssize_t size)
119
{
120
        ssize_t newsize;
121
122 2340929
        if (size < (int)VSB_MAXEXTENDSIZE) {
123 2291328
                newsize = VSB_MINEXTENDSIZE;
124 7780234
                while (newsize < size)
125 3197578
                        newsize *= 2;
126
        } else {
127 49601
                newsize = roundup2(size, VSB_MAXEXTENDINCR);
128
        }
129 2340929
        KASSERT(newsize >= size, ("%s: %d < %d\n", __func__, newsize, size));
130 2340929
        return (newsize);
131
}
132
133
/*
134
 * Extend an vsb.
135
 */
136
static ssize_t
137 1390022
VSB_extend(struct vsb *s, ssize_t addlen)
138
{
139
        char *newbuf;
140
        ssize_t newsize;
141
142 1390022
        if (!VSB_CANEXTEND(s))
143 2
                return (-1);
144 1390020
        newsize = VSB_extendsize(s->s_size + addlen);
145 1390021
        if (VSB_ISDYNAMIC(s))
146 1390021
                newbuf = realloc(s->s_buf, newsize);
147
        else
148 0
                newbuf = SBMALLOC(newsize);
149 1390021
        if (newbuf == NULL)
150 0
                return (-1);
151 1390021
        if (!VSB_ISDYNAMIC(s)) {
152 0
                memcpy(newbuf, s->s_buf, s->s_size);
153 0
                VSB_SETFLAG(s, VSB_DYNAMIC);
154
        }
155 1390021
        s->s_buf = newbuf;
156 1390021
        s->s_size = newsize;
157 1390021
        return (0);
158
}
159
160
static void
161 234880414
_vsb_indent(struct vsb *s)
162
{
163 234976844
        if (s->s_indent == 0 || s->s_error != 0 ||
164 192860
            (s->s_len > 0 && s->s_buf[s->s_len - 1] != '\n'))
165 234875754
                return;
166 4670
        if (VSB_FREESPACE(s) <= s->s_indent &&
167 10
            VSB_extend(s, s->s_indent) < 0) {
168 0
                s->s_error = ENOMEM;
169 0
                return;
170
        }
171 4660
        memset(s->s_buf + s->s_len, ' ', s->s_indent);
172 4660
        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 959882
VSB_newbuf(struct vsb *s, char *buf, int length, int flags)
182
{
183
184 959882
        memset(s, 0, sizeof(*s));
185 959882
        s->magic = VSB_MAGIC;
186 959882
        s->s_flags = flags;
187 959882
        s->s_size = length;
188 959882
        s->s_buf = buf;
189
190 959882
        if ((s->s_flags & VSB_AUTOEXTEND) == 0) {
191 8974
                KASSERT(s->s_size > 1,
192
                    ("attempt to create a too small vsb"));
193
        }
194
195 959882
        if (s->s_buf != NULL)
196 8974
                return (s);
197
198 950908
        if ((flags & VSB_AUTOEXTEND) != 0)
199 950908
                s->s_size = VSB_extendsize(s->s_size);
200
201 950911
        s->s_buf = SBMALLOC(s->s_size);
202 950911
        if (s->s_buf == NULL)
203 0
                return (NULL);
204 950911
        VSB_SETFLAG(s, VSB_DYNAMIC);
205 950911
        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 959886
VSB_new(struct vsb *s, char *buf, int length, int flags)
215
{
216
217 959886
        KASSERT(length >= 0,
218
            ("attempt to create an vsb of negative length (%d)", length));
219 959886
        KASSERT((flags & ~VSB_USRFLAGMSK) == 0,
220
            ("%s called with invalid flags", __func__));
221
222 959886
        flags &= VSB_USRFLAGMSK;
223 959886
        if (s != NULL)
224 8974
                return (VSB_newbuf(s, buf, length, flags));
225
226 950912
        s = SBMALLOC(sizeof(*s));
227 950912
        if (s == NULL)
228 0
                return (NULL);
229 950912
        if (VSB_newbuf(s, buf, length, flags) == NULL) {
230 0
                SBFREE(s);
231 0
                return (NULL);
232
        }
233 950912
        VSB_SETFLAG(s, VSB_DYNSTRUCT);
234 950912
        return (s);
235
}
236
237
/*
238
 * Clear an vsb and reset its position.
239
 */
240
void
241 2628203
VSB_clear(struct vsb *s)
242
{
243
244 2628203
        assert_VSB_integrity(s);
245
        /* don't care if it's finished or not */
246
247 2628133
        VSB_CLEARFLAG(s, VSB_FINISHED);
248 2628133
        s->s_error = 0;
249 2628133
        s->s_len = 0;
250 2628133
        s->s_indent = 0;
251 2628133
}
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 227412967
VSB_put_byte(struct vsb *s, int c)
260
{
261
262 227412967
        assert_VSB_integrity(s);
263 227414476
        assert_VSB_state(s, 0);
264
265 227413847
        if (s->s_error != 0)
266 0
                return;
267 227413847
        _vsb_indent(s);
268 227412997
        if (VSB_FREESPACE(s) <= 0) {
269 875870
                if (VSB_extend(s, 1) < 0)
270 0
                        s->s_error = ENOMEM;
271 875870
                if (s->s_error != 0)
272 0
                        return;
273
        }
274 227412997
        s->s_buf[s->s_len++] = (char)c;
275
}
276
277
/*
278
 * Append a byte string to an vsb.
279
 */
280
int
281 88655
VSB_bcat(struct vsb *s, const void *buf, ssize_t len)
282
{
283 88655
        assert_VSB_integrity(s);
284 88655
        assert_VSB_state(s, 0);
285
286 88655
        assert(len >= 0);
287 88655
        if (s->s_error != 0)
288 0
                return (-1);
289 88655
        if (len == 0)
290 6224
                return (0);
291 82431
        _vsb_indent(s);
292 82431
        if (len > VSB_FREESPACE(s)) {
293 16196
                if (VSB_extend(s, len - VSB_FREESPACE(s)) < 0)
294 2
                        s->s_error = ENOMEM;
295 16196
                if (s->s_error != 0)
296 2
                        return (-1);
297
        }
298 82429
        memcpy(s->s_buf + s->s_len, buf, len);
299 82429
        s->s_len += len;
300 82429
        return (0);
301
}
302
303
/*
304
 * Append a string to an vsb.
305
 */
306
int
307 3358935
VSB_cat(struct vsb *s, const char *str)
308
{
309
310 3358935
        assert_VSB_integrity(s);
311 3358937
        assert_VSB_state(s, 0);
312
313 3358780
        if (s->s_error != 0)
314 0
                return (-1);
315
316 201582650
        while (*str != '\0') {
317 194864942
                VSB_put_byte(s, *str++);
318 194865090
                if (s->s_error != 0)
319 0
                        return (-1);
320
        }
321 3358928
        return (0);
322
}
323
324
/*
325
 * Format the given argument list and append the resulting string to an vsb.
326
 */
327
int
328 7391546
VSB_vprintf(struct vsb *s, const char *fmt, va_list ap)
329
{
330
        va_list ap_copy;
331
        int len;
332
333 7391546
        assert_VSB_integrity(s);
334 7391457
        assert_VSB_state(s, 0);
335
336 7391411
        KASSERT(fmt != NULL,
337
            ("%s called with a NULL format string", __func__));
338
339 7391411
        if (s->s_error != 0)
340 0
                return (-1);
341 7391411
        _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 7889462
                va_copy(ap_copy, ap);
356 7889462
                len = vsnprintf(&s->s_buf[s->s_len], VSB_FREESPACE(s) + 1,
357
                    fmt, ap_copy);
358 7889462
                va_end(ap_copy);
359 7889462
                if (len < 0) {
360 0
                        s->s_error = errno;
361 0
                        return (-1);
362
                }
363 8387408
        } while (len > VSB_FREESPACE(s) &&
364 7889462
            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 7391467
        if (VSB_FREESPACE(s) < len)
376 0
                len = VSB_FREESPACE(s);
377 7391467
        s->s_len += len;
378 7391467
        if (!VSB_HASROOM(s) && !VSB_CANEXTEND(s))
379 0
                s->s_error = ENOMEM;
380
381 7391467
        KASSERT(s->s_len < s->s_size,
382
            ("wrote past end of vsb (%d >= %d)", s->s_len, s->s_size));
383
384 7391467
        if (s->s_error != 0)
385 0
                return (-1);
386 7391467
        return (0);
387
}
388
389
/*
390
 * Format the given arguments and append the resulting string to an vsb.
391
 */
392
int
393 3532641
VSB_printf(struct vsb *s, const char *fmt, ...)
394
{
395
        va_list ap;
396
        int result;
397
398 3532641
        va_start(ap, fmt);
399 3532641
        result = VSB_vprintf(s, fmt, ap);
400 3532644
        va_end(ap);
401 3532644
        return (result);
402
}
403
404
/*
405
 * Append a character to an vsb.
406
 */
407
int
408 32572082
VSB_putc(struct vsb *s, int c)
409
{
410
411 32572082
        VSB_put_byte(s, c);
412 32570173
        if (s->s_error != 0)
413 0
                return (-1);
414 32570173
        return (0);
415
}
416
417
/*
418
 * Check if an vsb has an error.
419
 */
420
int
421 982
VSB_error(const struct vsb *s)
422
{
423
424 982
        return (s->s_error);
425
}
426
427
/*
428
 * Finish off an vsb.
429
 */
430
int
431 2568417
VSB_finish(struct vsb *s)
432
{
433
434 2568417
        assert_VSB_integrity(s);
435 2568375
        assert_VSB_state(s, 0);
436
437 2568341
        s->s_buf[s->s_len] = '\0';
438 2568341
        VSB_SETFLAG(s, VSB_FINISHED);
439 2568341
        errno = s->s_error;
440 2568403
        if (s->s_error)
441 2
                return (-1);
442 2568401
        return (0);
443
}
444
445
/*
446
 * Return a pointer to the vsb data.
447
 */
448
char *
449 2529237
VSB_data(const struct vsb *s)
450
{
451
452 2529237
        assert_VSB_integrity(s);
453 2529217
        assert_VSB_state(s, VSB_FINISHED);
454
455 2529207
        return (s->s_buf);
456
}
457
458
/*
459
 * Return the length of the vsb data.
460
 */
461
ssize_t
462 1302857
VSB_len(const struct vsb *s)
463
{
464
465 1302857
        assert_VSB_integrity(s);
466
        /* don't care if it's finished or not */
467
468 1302856
        if (s->s_error != 0)
469 0
                return (-1);
470 1302856
        return (s->s_len);
471
}
472
473
/*
474
 * Clear an vsb, free its buffer if necessary.
475
 */
476
void
477 901061
VSB_delete(struct vsb *s)
478
{
479
        int isdyn;
480
481 901061
        assert_VSB_integrity(s);
482
        /* don't care if it's finished or not */
483
484 901060
        if (VSB_ISDYNAMIC(s))
485 901061
                SBFREE(s->s_buf);
486 901060
        isdyn = VSB_ISDYNSTRUCT(s);
487 901060
        memset(s, 0, sizeof(*s));
488 901060
        if (isdyn)
489 901060
                SBFREE(s);
490 901060
}
491
492
void
493 844215
VSB_destroy(struct vsb **s)
494
{
495 844215
        VSB_delete(*s);
496 844214
        *s = NULL;
497 844214
}
498
499
/*
500
 * Quote a string
501
 */
502
void
503 260962
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 260962
        int quote = 0;
508 260962
        int nl = 0;
509
        const unsigned char *u, *w;
510
511 260962
        assert(v != NULL);
512 260962
        if (len == -1)
513 89134
                len = strlen(v);
514
515 260962
        if (len == 0 && (how & VSB_QUOTE_CSTR)) {
516 338
                VSB_printf(s, "%s\"\"", pfx);
517 338
                return;
518 260624
        } else if (len == 0)
519 8666
                return;
520
521 251958
        VSB_cat(s, pfx);
522
523 251958
        if (how & VSB_QUOTE_HEX) {
524 1584
                u = v;
525 4564
                for (w = u; w < u + len; w++)
526 3974
                        if (*w != 0x00)
527 994
                                break;
528 1584
                VSB_printf(s, "0x");
529 1584
                if (w == u + len && len > 4) {
530 14
                        VSB_printf(s, "0...0");
531
                } else {
532 77572
                        for (w = u; w < u + len; w++)
533 76002
                                VSB_printf(s, "%02x", *w);
534
                }
535 1584
                return;
536
        }
537 250374
        p = v;
538
539 2760883
        for (q = p; q < p + len; q++) {
540 2661251
                if (!isgraph(*q) || *q == '"' || *q == '\\') {
541 150744
                        quote++;
542 150744
                        break;
543
                }
544
        }
545 250376
        if (!quote && !(how & (VSB_QUOTE_JSON|VSB_QUOTE_CSTR))) {
546 52115
                (void)VSB_bcat(s, p, len);
547 89368
                if ((how & (VSB_QUOTE_UNSAFE|VSB_QUOTE_NONL)) &&
548 37253
                    p[len-1] != '\n')
549 37253
                        (void)VSB_putc(s, '\n');
550 52115
                return;
551
        }
552
553 198261
        if (how & VSB_QUOTE_CSTR)
554 79726
                (void)VSB_putc(s, '"');
555
556 21702039
        for (q = p; q < p + len; q++) {
557 21503782
                if (nl)
558 192661
                        VSB_cat(s, pfx);
559 21506421
                nl = 0;
560 21506421
                switch (*q) {
561
                case '?':
562 20197
                        if (how & VSB_QUOTE_CSTR)
563 3618
                                (void)VSB_putc(s, '\\');
564 20197
                        (void)VSB_putc(s, *q);
565 17890
                        break;
566
                case ' ':
567 3502752
                        (void)VSB_putc(s, *q);
568 3502779
                        break;
569
                case '\\':
570
                case '"':
571 202365
                        if (!(how & VSB_QUOTE_UNSAFE))
572 146314
                                (void)VSB_putc(s, '\\');
573 202365
                        (void)VSB_putc(s, *q);
574 202365
                        break;
575
                case '\n':
576 669928
                        if (how & VSB_QUOTE_CSTR) {
577 432450
                                (void)VSB_printf(s, "\\n\"\n%s\t\"", pfx);
578 237478
                        } else if (how & (VSB_QUOTE_NONL|VSB_QUOTE_UNSAFE)) {
579 236138
                                (void)VSB_printf(s, "\n");
580 236154
                                nl = 1;
581
                        } else {
582 1340
                                (void)VSB_printf(s, "\\n");
583
                        }
584 669944
                        break;
585
                case '\r':
586 95248
                        (void)VSB_cat(s, "\\r");
587 95241
                        break;
588
                case '\t':
589 89579
                        (void)VSB_cat(s, "\\t");
590 89579
                        break;
591
                default:
592
                        /* XXX: Implement VSB_QUOTE_JSON */
593 16926352
                        if (isgraph(*q))
594 16913975
                                (void)VSB_putc(s, *q);
595
                        else
596 13797
                                (void)VSB_printf(s, "\\%o", *q & 0xff);
597 16925860
                        break;
598
                }
599
        }
600 198257
        if (how & VSB_QUOTE_CSTR)
601 79726
                (void)VSB_putc(s, '"');
602 198257
        if ((how & (VSB_QUOTE_NONL|VSB_QUOTE_UNSAFE)) && !nl)
603 70848
                (void)VSB_putc(s, '\n');
604
}
605
606
void
607 100760
VSB_quote(struct vsb *s, const void *v, int len, int how)
608
{
609 100760
        VSB_quote_pfx(s, "", v, len, how);
610 100760
}
611
612
/*
613
 * Indentation
614
 */
615
616
void
617 1932
VSB_indent(struct vsb * s, int i)
618
{
619
620 1932
        assert_VSB_integrity(s);
621 1932
        if (s->s_indent + i < 0)
622 0
                s->s_error = EINVAL;
623
        else
624 1932
                s->s_indent += i;
625 1932
}