varnish-cache/lib/libvarnish/vsb.c
1
/*-
2
 * Copyright (c) 2000-2008 Poul-Henning Kamp <phk@FreeBSD.org>
3
 * Copyright (c) 2000-2008 Dag-Erling Coïdan Smørgrav
4
 * All rights reserved.
5
 *
6
 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer
13
 *    in this position and unchanged.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
__FBSDID("$FreeBSD: head/sys/kern/subr_vsb.c 222004 2011-05-17 06:36:32Z phk $")
30
 */
31
32
#include "config.h"
33
34
#include <ctype.h>
35
#include <stdarg.h>
36
#include <stdio.h>
37
#include <stdint.h>
38
#include <stdlib.h>
39
#include <string.h>
40
#include <unistd.h>
41
42
#include "vdef.h"
43
#include "vas.h"        // XXX Flexelint "not used" - but req'ed for assert()
44
#include "vsb.h"
45
46
#define KASSERT(e, m)           assert(e)
47
#define SBMALLOC(size)          malloc(size)
48
#define SBFREE(buf)             free(buf)
49
50
#define rndup2(x, y)    (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
51
52
/*
53
 * Predicates
54
 */
55
#define VSB_ISDYNAMIC(s)        ((s)->s_flags & VSB_DYNAMIC)
56
#define VSB_ISDYNSTRUCT(s)      ((s)->s_flags & VSB_DYNSTRUCT)
57
#define VSB_HASROOM(s)          ((s)->s_len < (s)->s_size - 1L)
58
#define VSB_FREESPACE(s)        ((s)->s_size - ((s)->s_len + 1L))
59
#define VSB_CANEXTEND(s)        ((s)->s_flags & VSB_AUTOEXTEND)
60
61
/*
62
 * Set / clear flags
63
 */
64
#define VSB_SETFLAG(s, f)       do { (s)->s_flags |= (f); } while (0)
65
#define VSB_CLEARFLAG(s, f)     do { (s)->s_flags &= ~(f); } while (0)
66
67
#define VSB_MINEXTENDSIZE       16              /* Should be power of 2. */
68
69
#ifdef PAGE_SIZE
70
#define VSB_MAXEXTENDSIZE       PAGE_SIZE
71
#define VSB_MAXEXTENDINCR       PAGE_SIZE
72
#else
73
#define VSB_MAXEXTENDSIZE       4096
74
#define VSB_MAXEXTENDINCR       4096
75
#endif
76
77
/*
78
 * Debugging support
79
 */
80
#if !defined(NDEBUG)
81
static void
82 2203935957
_assert_VSB_integrity(const char *fun, const struct vsb *s)
83
{
84
85 2203935957
        (void)fun;
86 2203935957
        (void)s;
87 2203935957
        KASSERT(s != NULL,
88
            ("%s called with a NULL vsb pointer", fun));
89 2203934721
        KASSERT(s->magic == VSB_MAGIC,
90
            ("%s called wih an bogus vsb pointer", fun));
91 2203958754
        KASSERT(s->s_buf != NULL,
92
            ("%s called with uninitialized or corrupt vsb", fun));
93 2203961514
        KASSERT(s->s_len < s->s_size,
94
            ("wrote past end of vsb (%d >= %d)", s->s_len, s->s_size));
95 2203992337
}
96
97
static void
98 2062697171
_assert_VSB_state(const char *fun, const struct vsb *s, int state)
99
{
100
101 2062697171
        (void)fun;
102 2062697171
        (void)s;
103 2062697171
        (void)state;
104 2062697171
        KASSERT((s->s_flags & VSB_FINISHED) == state,
105
            ("%s called with %sfinished or corrupt vsb", fun,
106
            (state ? "un" : "")));
107 2062746303
}
108
#define assert_VSB_integrity(s) _assert_VSB_integrity(__func__, (s))
109
#define assert_VSB_state(s, i)   _assert_VSB_state(__func__, (s), (i))
110
#else
111
#define assert_VSB_integrity(s) do { } while (0)
112
#define assert_VSB_state(s, i)   do { } while (0)
113
#endif
114
115
#ifdef CTASSERT
116
CTASSERT(powerof2(VSB_MAXEXTENDSIZE));
117
CTASSERT(powerof2(VSB_MAXEXTENDINCR));
118
#endif
119
120
static ssize_t
121 116832066
VSB_extendsize(ssize_t size)
122
{
123
        ssize_t newsize;
124
125 116832066
        if (size < (int)VSB_MAXEXTENDSIZE) {
126 115821665
                newsize = VSB_MINEXTENDSIZE;
127 267701670
                while (newsize < size)
128 151880008
                        newsize *= 2;
129 115821671
        } else {
130 1010404
                newsize = rndup2(size, VSB_MAXEXTENDINCR);
131
        }
132 116832079
        KASSERT(newsize >= size, ("%s: %d < %d\n", __func__, newsize, size));
133 116832089
        return (newsize);
134
}
135
136
/*
137
 * Extend an vsb.
138
 */
139
static ssize_t
140 66261369
VSB_extend(struct vsb *s, ssize_t addlen)
141
{
142
        char *newbuf;
143
        ssize_t newsize;
144
145 66261369
        if (!VSB_CANEXTEND(s))
146 1200
                return (-1);
147 66260171
        newsize = VSB_extendsize(s->s_size + addlen);
148 66260171
        if (VSB_ISDYNAMIC(s))
149 66260169
                newbuf = realloc(s->s_buf, newsize);
150
        else
151 0
                newbuf = SBMALLOC(newsize);
152 66260174
        if (newbuf == NULL)
153 0
                return (-1);
154 66260174
        if (!VSB_ISDYNAMIC(s)) {
155 0
                memcpy(newbuf, s->s_buf, s->s_size);
156 0
                VSB_SETFLAG(s, VSB_DYNAMIC);
157 0
        }
158 66260175
        s->s_buf = newbuf;
159 66260175
        s->s_size = newsize;
160 66260175
        return (0);
161 66261373
}
162
163
static void
164 1674545240
_vsb_indent(struct vsb *s)
165
{
166 1676463608
        if (s->s_indent == 0 || s->s_error != 0 ||
167 1918368
            (s->s_len > 0 && s->s_buf[s->s_len - 1] != '\n'))
168 1674421938
                return;
169 127720
        if (VSB_FREESPACE(s) <= s->s_indent &&
170 280
            VSB_extend(s, s->s_indent) < 0) {
171 0
                s->s_error = ENOMEM;
172 0
                return;
173
        }
174 127720
        memset(s->s_buf + s->s_len, ' ', s->s_indent);
175 127720
        s->s_len += s->s_indent;
176 1674540475
}
177
178
/*
179
 * Initialize the internals of an vsb.
180
 * If buf is non-NULL, it points to a static or already-allocated string
181
 * big enough to hold at least length characters.
182
 */
183
static struct vsb *
184 51511110
VSB_newbuf(struct vsb *s, char *buf, int length, int flags)
185
{
186
187 51511110
        memset(s, 0, sizeof(*s));
188 51511110
        s->magic = VSB_MAGIC;
189 51511110
        s->s_flags = flags;
190 51511110
        s->s_size = length;
191 51511110
        s->s_buf = buf;
192
193 51511110
        if ((s->s_flags & VSB_AUTOEXTEND) == 0) {
194 939260
                KASSERT(s->s_size > 1,
195
                    ("attempt to create a too small vsb"));
196 939254
        }
197
198 51511188
        if (s->s_buf != NULL)
199 939250
                return (s);
200
201 50571936
        if ((flags & VSB_AUTOEXTEND) != 0)
202 50571938
                s->s_size = VSB_extendsize(s->s_size);
203
204 50571934
        s->s_buf = SBMALLOC(s->s_size);
205 50571934
        if (s->s_buf == NULL)
206 0
                return (NULL);
207 50571950
        VSB_SETFLAG(s, VSB_DYNAMIC);
208 50571954
        return (s);
209 51511206
}
210
211
/*
212
 * Initialize an vsb.
213
 * If buf is non-NULL, it points to a static or already-allocated string
214
 * big enough to hold at least length characters.
215
 */
216
struct vsb *
217 0
VSB_new(struct vsb *s, char *buf, int length, int flags)
218
{
219
220 0
        KASSERT(length >= 0,
221
            ("attempt to create an vsb of negative length (%d)", length));
222 0
        KASSERT((flags & ~VSB_USRFLAGMSK) == 0,
223
            ("%s called with invalid flags", __func__));
224
225 0
        flags &= VSB_USRFLAGMSK;
226 0
        if (s != NULL)
227 0
                return (VSB_newbuf(s, buf, length, flags));
228
229 0
        s = SBMALLOC(sizeof(*s));
230 0
        if (s == NULL)
231 0
                return (NULL);
232 0
        if (VSB_newbuf(s, buf, length, flags) == NULL) {
233 0
                SBFREE(s);
234 0
                return (NULL);
235
        }
236 0
        VSB_SETFLAG(s, VSB_DYNSTRUCT);
237 0
        return (s);
238 0
}
239
240
struct vsb *
241 939197
VSB_init(struct vsb *s, void *buf, ssize_t length)
242
{
243 939197
        AN(s);
244 939199
        AN(buf);
245
246 939229
        KASSERT(length >= 0,
247
            ("attempt to create an vsb of negative length (%zd)", length));
248 939204
        return (VSB_newbuf(s, buf, length, VSB_FIXEDLEN));
249
}
250
251
/*
252
 * Allocate a dynamic vsb
253
 */
254
struct vsb *
255 50571938
VSB_new_auto(void)
256
{
257
        struct vsb *s;
258
259 50571938
        s = SBMALLOC(sizeof(*s));
260 50571938
        if (s == NULL)
261 0
                return (NULL);
262 50571947
        if (VSB_newbuf(s, NULL, 0, VSB_AUTOEXTEND) == NULL) {
263 0
                SBFREE(s);
264 0
                return (NULL);
265
        }
266 50571950
        VSB_SETFLAG(s, VSB_DYNSTRUCT);
267 50571949
        return (s);
268 50571949
}
269
270
/*
271
 * Clear an vsb and reset its position.
272
 */
273
void
274 63689326
VSB_clear(struct vsb *s)
275
{
276
277 63689326
        assert_VSB_integrity(s);
278
        /* don't care if it's finished or not */
279
280 63689326
        VSB_CLEARFLAG(s, VSB_FINISHED);
281 63688763
        s->s_error = 0;
282 63688763
        s->s_len = 0;
283 63688763
        s->s_indent = 0;
284 63688763
}
285
286
/*
287
 * Append a byte to an vsb.  This is the core function for appending
288
 * to an vsb and is the main place that deals with extending the
289
 * buffer and marking overflow.
290
 */
291
static void
292 1127227285
VSB_put_byte(struct vsb *s, int c)
293
{
294
295 1127227285
        assert_VSB_integrity(s);
296 1127227285
        assert_VSB_state(s, 0);
297
298 1127227285
        if (s->s_error != 0)
299 0
                return;
300 1127267088
        _vsb_indent(s);
301 1127267088
        if (VSB_FREESPACE(s) <= 0) {
302 18877529
                if (VSB_extend(s, 1) < 0)
303 0
                        s->s_error = ENOMEM;
304 18877531
                if (s->s_error != 0)
305 0
                        return;
306 18877530
        }
307 1127258716
        s->s_buf[s->s_len++] = (char)c;
308 1127258716
}
309
310
/*
311
 * Append a byte string to an vsb.
312
 */
313
int
314 209737311
VSB_bcat(struct vsb *s, const void *buf, ssize_t len)
315
{
316 209737311
        assert_VSB_integrity(s);
317 209737311
        assert_VSB_state(s, 0);
318
319 209737311
        assert(len >= 0);
320 209735602
        if (s->s_error != 0)
321 0
                return (-1);
322 209735619
        if (len == 0)
323 5200344
                return (0);
324 204535313
        _vsb_indent(s);
325 204535313
        if (len > VSB_FREESPACE(s)) {
326 15607171
                if (VSB_extend(s, len - VSB_FREESPACE(s)) < 0)
327 320
                        s->s_error = ENOMEM;
328 15607182
                if (s->s_error != 0)
329 320
                        return (-1);
330 15606862
        }
331 204535943
        memcpy(s->s_buf + s->s_len, buf, len);
332 204535943
        s->s_len += len;
333 204535943
        return (0);
334 209735688
}
335
336
/*
337
 * Append a string to an vsb.
338
 */
339
int
340 203788266
VSB_cat(struct vsb *s, const char *str)
341
{
342
        const char *nl;
343
        size_t l;
344
345 203788266
        assert_VSB_integrity(s);
346 203788266
        assert_VSB_state(s, 0);
347 203788266
        KASSERT(str != NULL,
348
            ("%s called with a NULL str pointer", __func__));
349
350 203788049
        if (s->s_error != 0)
351 200
                return (-1);
352
353 203812286
        while (s->s_indent > 0 && (nl = strchr(str, '\n')) != NULL) {
354 24440
                l = (nl - str) + 1;
355 24440
                if (VSB_bcat(s, str, l) < 0)
356 0
                        return (-1);
357 24440
                str += l;
358
        }
359
360 203787923
        l = strlen(str);
361 203787923
        return (VSB_bcat(s, str, l));
362 203786100
}
363
364
/*
365
 * Format the given argument list and append the resulting string to an vsb.
366
 */
367
int
368 342849789
VSB_vprintf(struct vsb *s, const char *fmt, va_list ap)
369
{
370
        va_list ap_copy;
371
        int len;
372
373 342849789
        assert_VSB_integrity(s);
374 342849789
        assert_VSB_state(s, 0);
375
376 342849789
        KASSERT(fmt != NULL,
377
            ("%s called with a NULL format string", __func__));
378
379 342847996
        if (s->s_error != 0)
380 0
                return (-1);
381 342847258
        _vsb_indent(s);
382
383
        /*
384
         * For the moment, there is no way to get vsnprintf(3) to hand
385
         * back a character at a time, to push everything into
386
         * VSB_putc_func() as was done for the kernel.
387
         *
388
         * In userspace, while drains are useful, there's generally
389
         * not a problem attempting to malloc(3) on out of space.  So
390
         * expand a userland vsb if there is not enough room for the
391
         * data produced by VSB_[v]printf(3).
392
         */
393
394 342847258
        do {
395 374621020
                va_copy(ap_copy, ap);
396 749242040
                len = vsnprintf(&s->s_buf[s->s_len], VSB_FREESPACE(s) + 1,
397 374621020
                    fmt, ap_copy);
398 374621020
                va_end(ap_copy);
399 374621020
                if (len < 0) {
400 0
                        s->s_error = errno;
401 0
                        return (-1);
402
                }
403 406402615
        } while (len > VSB_FREESPACE(s) &&
404 31776414
            VSB_extend(s, len - VSB_FREESPACE(s)) == 0);
405
406
        /*
407
         * s->s_len is the length of the string, without the terminating nul.
408
         * When updating s->s_len, we must subtract 1 from the length that
409
         * we passed into vsnprintf() because that length includes the
410
         * terminating nul.
411
         *
412
         * vsnprintf() returns the amount that would have been copied,
413
         * given sufficient space, so don't over-increment s_len.
414
         */
415 342849752
        if (VSB_FREESPACE(s) < len)
416 880
                len = VSB_FREESPACE(s);
417 342849726
        s->s_len += len;
418 342849726
        if (!VSB_HASROOM(s) && !VSB_CANEXTEND(s))
419 880
                s->s_error = ENOMEM;
420
421 342849688
        KASSERT(s->s_len < s->s_size,
422
            ("wrote past end of vsb (%d >= %d)", s->s_len, s->s_size));
423
424 342849684
        if (s->s_error != 0)
425 880
                return (-1);
426 342848416
        return (0);
427 342849304
}
428
429
/*
430
 * Format the given arguments and append the resulting string to an vsb.
431
 */
432
int
433 179200326
VSB_printf(struct vsb *s, const char *fmt, ...)
434
{
435
        va_list ap;
436
        int result;
437
438 179200326
        va_start(ap, fmt);
439 179200326
        result = VSB_vprintf(s, fmt, ap);
440 179200326
        va_end(ap);
441 179200326
        return (result);
442
}
443
444
/*
445
 * Append a character to an vsb.
446
 */
447
int
448 1127194107
VSB_putc(struct vsb *s, int c)
449
{
450
451 1127194107
        VSB_put_byte(s, c);
452 1127194107
        if (s->s_error != 0)
453 0
                return (-1);
454 1127236966
        return (0);
455 1127238246
}
456
457
/*
458
 * Check if an vsb has an error.
459
 */
460
int
461 40341
VSB_error(const struct vsb *s)
462
{
463
464 40341
        return (s->s_error);
465
}
466
467
/*
468
 * Finish off an vsb.
469
 */
470
int
471 87185698
VSB_finish(struct vsb *s)
472
{
473
474 87185698
        assert_VSB_integrity(s);
475 87185698
        assert_VSB_state(s, 0);
476
477 87185698
        s->s_buf[s->s_len] = '\0';
478 87185698
        VSB_SETFLAG(s, VSB_FINISHED);
479 87185908
        errno = s->s_error;
480 87185908
        if (s->s_error)
481 1200
                return (-1);
482 87184641
        return (0);
483 87185822
}
484
485
/*
486
 * Return a pointer to the vsb data.
487
 */
488
char *
489 89809653
VSB_data(const struct vsb *s)
490
{
491
492 89809653
        assert_VSB_integrity(s);
493 89809653
        assert_VSB_state(s, VSB_FINISHED);
494
495 89809653
        return (s->s_buf);
496
}
497
498
/*
499
 * Return the length of the vsb data.
500
 */
501
ssize_t
502 34432598
VSB_len(const struct vsb *s)
503
{
504
505 34432598
        assert_VSB_integrity(s);
506
        /* don't care if it's finished or not */
507
508 34432598
        if (s->s_error != 0)
509 0
                return (-1);
510 34431178
        return (s->s_len);
511 34431232
}
512
513
/*
514
 * Clear an vsb, free its buffer if necessary.
515
 */
516
void
517 0
VSB_delete(struct vsb *s)
518
{
519
        int isdyn;
520
521 0
        assert_VSB_integrity(s);
522
        /* don't care if it's finished or not */
523
524 0
        if (VSB_ISDYNAMIC(s))
525 0
                SBFREE(s->s_buf);
526 0
        isdyn = VSB_ISDYNSTRUCT(s);
527 0
        memset(s, 0, sizeof(*s));
528 0
        if (isdyn)
529 0
                SBFREE(s);
530 0
}
531
532
void
533 906701
VSB_fini(struct vsb *s)
534
{
535
536 906701
        assert_VSB_integrity(s);
537 906701
        assert(!VSB_ISDYNAMIC(s));
538 906685
        assert(!VSB_ISDYNSTRUCT(s));
539 906693
        memset(s, 0, sizeof(*s));
540 906693
}
541
542
void
543 42315558
VSB_destroy(struct vsb **s)
544
{
545
546 42315558
        AN(s);
547 42315557
        assert_VSB_integrity(*s);
548 42315557
        assert(VSB_ISDYNAMIC(*s));
549 42315562
        assert(VSB_ISDYNSTRUCT(*s));
550 42315560
        SBFREE((*s)->s_buf);
551 42315560
        memset(*s, 0, sizeof(**s));
552 42315560
        SBFREE(*s);
553 42315560
        *s = NULL;
554 42315560
}
555
556
/*
557
 * Quote a string
558
 */
559
560
static void
561 38800
vsb_quote_hex(struct vsb *s, const uint8_t *u, size_t len)
562
{
563
        const uint8_t *w;
564
565 38800
        VSB_cat(s, "0x");
566 109440
        for (w = u; w < u + len; w++)
567 95680
                if (*w != 0x00)
568 25040
                        break;
569 38800
        if (w == u + len && len > 4) {
570 360
                VSB_cat(s, "0...0");
571 360
        } else {
572 1621040
                for (w = u; w < u + len; w++)
573 1582600
                        VSB_printf(s, "%02x", *w);
574
        }
575 38800
}
576
577
void
578 8153446
VSB_quote_pfx(struct vsb *s, const char *pfx, const void *v, int len, int how)
579
{
580 8153446
        const uint8_t *p = v;
581
        const uint8_t *q;
582 8153446
        int quote = 0;
583
        int nl;
584
585 8153446
        nl = how &
586
            (VSB_QUOTE_JSON|VSB_QUOTE_HEX|VSB_QUOTE_CSTR|VSB_QUOTE_UNSAFE);
587 8153446
        AZ(nl & (nl - 1)); // Only one bit can be set
588
589 8153405
        if (how & VSB_QUOTE_ESCHEX)
590 3839375
                AZ(how & (VSB_QUOTE_JSON|VSB_QUOTE_HEX));
591
592 8153406
        if (how & VSB_QUOTE_UNSAFE)
593 3830058
                how |= VSB_QUOTE_NONL;
594
595 8153418
        assert(p != NULL);
596 8153488
        if (len == -1)
597 4004360
                len = strlen(v);
598
599 8153491
        if (len == 0 && (how & VSB_QUOTE_CSTR)) {
600 7360
                VSB_printf(s, "%s\"\"", pfx);
601 7360
                if ((how & VSB_QUOTE_NONL))
602 0
                        VSB_putc(s, '\n');
603 7360
        }
604
605 8153528
        if (len == 0)
606 286424
                return;
607
608 7867082
        VSB_cat(s, pfx);
609
610 7867082
        if (how & VSB_QUOTE_HEX) {
611 38800
                vsb_quote_hex(s, v, len);
612 38800
                if (how & VSB_QUOTE_NONL)
613 40
                        VSB_putc(s, '\n');
614 38800
                return;
615
        }
616
617 7827839
        if (how & VSB_QUOTE_CSTR)
618 3851640
                VSB_putc(s, '"');
619
620 164926554
        for (q = p; q < p + len; q++) {
621
                if (
622 159612453
                    *q < 0x20 ||
623 157422490
                    *q == '"' ||
624 157392710
                    *q == '\\' ||
625 157388002
                    (*q == '?' && (how & VSB_QUOTE_CSTR)) ||
626 157101109
                    (*q > 0x7e && !(how & VSB_QUOTE_JSON))
627
                ) {
628 2512502
                        quote++;
629 2512502
                        break;
630
                }
631 157098757
        }
632
633 7828316
        if (!quote) {
634 5315806
                VSB_bcat(s, p, len);
635 5315806
                if ((how & VSB_QUOTE_NONL) &&
636 2414398
                    p[len-1] != '\n')
637 2414395
                        (void)VSB_putc(s, '\n');
638 5315537
                if (how & VSB_QUOTE_CSTR)
639 2520840
                        VSB_putc(s, '"');
640 5315541
                return;
641
        }
642
643 2512510
        nl = 0;
644 509796599
        for (q = p; q < p + len; q++) {
645 507282969
                if (nl)
646 4865325
                        VSB_cat(s, pfx);
647 507297668
                nl = 0;
648 507297668
                switch (*q) {
649
                case '?':
650
                        /* Avoid C Trigraph insanity */
651 823705
                        if (how & VSB_QUOTE_CSTR && !(how & VSB_QUOTE_JSON))
652 414120
                                (void)VSB_putc(s, '\\');
653 823705
                        (void)VSB_putc(s, *q);
654 823705
                        break;
655
                case '\\':
656
                case '"':
657 5140997
                        if (!(how & VSB_QUOTE_UNSAFE))
658 3614200
                                (void)VSB_putc(s, '\\');
659 5140997
                        (void)VSB_putc(s, *q);
660 5140997
                        break;
661
                case '\n':
662 21463875
                        if (how & VSB_QUOTE_CSTR) {
663 15481600
                                VSB_printf(s, "\\n\"\n%s\"", pfx);
664 21463857
                        } else if (how & VSB_QUOTE_JSON) {
665 38560
                                VSB_printf(s, "\\n");
666 5982267
                        } else if (how & VSB_QUOTE_NONL) {
667 5943229
                                VSB_putc(s, *q);
668 5943229
                                nl = 1;
669 5943229
                        } else {
670 480
                                VSB_printf(s, "\\n");
671
                        }
672 21463925
                        break;
673
                case '\r':
674 2319595
                        VSB_cat(s, "\\r");
675 2319595
                        break;
676
                case '\t':
677 7191236
                        VSB_cat(s, "\\t");
678 7191236
                        break;
679
                case '\v':
680 1534
                        VSB_cat(s, "\\v");
681 1534
                        break;
682
                default:
683 470390896
                        if (0x20 <= *q && *q <= 0x7e)
684 469719139
                                VSB_putc(s, *q);
685 628516
                        else if (*q > 0x7e && (how & VSB_QUOTE_JSON))
686 160
                                VSB_putc(s, *q);
687 628360
                        else if (how & VSB_QUOTE_JSON)
688 80
                                VSB_printf(s, "\\u%04x", *q);
689 628263
                        else if (how & VSB_QUOTE_ESCHEX)
690 625702
                                VSB_printf(s, "\\x%02x", *q);
691
                        else
692 2560
                                VSB_printf(s, "\\%03o", *q);
693 470384931
                        break;
694
                }
695 507319329
        }
696 2512500
        if (how & VSB_QUOTE_CSTR)
697 1330800
                VSB_putc(s, '"');
698 2512492
        if ((how & VSB_QUOTE_NONL) && !nl)
699 94829
                VSB_putc(s, '\n');
700 8153261
}
701
702
void
703 4202880
VSB_quote(struct vsb *s, const void *v, int len, int how)
704
{
705 4202880
        VSB_quote_pfx(s, "", v, len, how);
706 4202880
}
707
708
/*
709
 * Indentation
710
 */
711
712
void
713 50080
VSB_indent(struct vsb *s, int i)
714
{
715
716 50080
        assert_VSB_integrity(s);
717 50080
        if (s->s_indent + i < 0)
718 0
                s->s_error = EINVAL;
719
        else
720 50080
                s->s_indent += i;
721 50080
}
722
723
int
724 2260421
VSB_tofile(const struct vsb *s, int fd)
725
{
726
        int sz;
727
728 2260421
        assert_VSB_integrity(s);
729 2260421
        assert_VSB_state(s, VSB_FINISHED);
730 2260421
        assert(s->s_len >= 0);
731 2260418
        sz = write(fd, s->s_buf, s->s_len);
732 2260418
        return (sz == s->s_len ? 0 : -1);
733
}