Coverage Report

Created: 2023-06-07 06:09

/src/varnish-cache/bin/varnishd/cache/cache_ws_common.c
Line
Count
Source (jump to first uncovered line)
1
/*-
2
 * Copyright (c) 2006 Verdens Gang AS
3
 * Copyright (c) 2006-2021 Varnish Software AS
4
 * All rights reserved.
5
 *
6
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
7
 * Author: Dridi Boukelmoune <dridi.boukelmoune@gmail.com>
8
 *
9
 * SPDX-License-Identifier: BSD-2-Clause
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 * 1. Redistributions of source code must retain the above copyright
15
 *    notice, this list of conditions and the following disclaimer.
16
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in the
18
 *    documentation and/or other materials provided with the distribution.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 *
32
 */
33
34
#include "config.h"
35
36
#include <stdio.h>
37
38
#include "cache_varnishd.h"
39
40
void
41
WS_Id(const struct ws *ws, char *id)
42
0
{
43
44
0
  WS_Assert(ws);
45
0
  AN(id);
46
0
  memcpy(id, ws->id, WS_ID_SIZE);
47
0
  id[0] |= 0x20;      // cheesy tolower()
48
0
}
49
50
void
51
WS_MarkOverflow(struct ws *ws)
52
0
{
53
0
  CHECK_OBJ_NOTNULL(ws, WS_MAGIC);
54
55
0
  ws->id[0] &= ~0x20;   // cheesy toupper()
56
0
}
57
58
static void
59
ws_ClearOverflow(struct ws *ws)
60
790
{
61
790
  CHECK_OBJ_NOTNULL(ws, WS_MAGIC);
62
63
790
  ws->id[0] |= 0x20;    // cheesy tolower()
64
790
}
65
66
int
67
WS_Overflowed(const struct ws *ws)
68
0
{
69
0
  CHECK_OBJ_NOTNULL(ws, WS_MAGIC);
70
0
  AN(ws->id[0]);
71
72
0
  if (ws->id[0] & 0x20)   // cheesy islower()
73
0
    return (0);
74
0
  return (1);
75
0
}
76
77
/*
78
 * Reset the WS to a cookie or its start and clears any overflow
79
 *
80
 * for varnishd internal use only
81
 */
82
83
void
84
WS_Rollback(struct ws *ws, uintptr_t pp)
85
790
{
86
87
790
  WS_Assert(ws);
88
89
790
  if (pp == 0)
90
790
    pp = (uintptr_t)ws->s;
91
790
  ws_ClearOverflow(ws);
92
790
  WS_Reset(ws, pp);
93
790
}
94
95
/*--------------------------------------------------------------------*/
96
97
const char *
98
WS_Printf(struct ws *ws, const char *fmt, ...)
99
0
{
100
0
  unsigned u, v;
101
0
  va_list ap;
102
0
  char *p;
103
104
0
  u = WS_ReserveAll(ws);
105
0
  p = ws->f;
106
0
  va_start(ap, fmt);
107
0
  v = vsnprintf(p, u, fmt, ap);
108
0
  va_end(ap);
109
0
  if (v >= u) {
110
0
    WS_Release(ws, 0);
111
0
    WS_MarkOverflow(ws);
112
0
    p = NULL;
113
0
  } else {
114
0
    WS_Release(ws, v + 1);
115
0
  }
116
0
  return (p);
117
0
}
118
119
/*---------------------------------------------------------------------
120
 * Build a VSB on a workspace.
121
 * Usage pattern:
122
 *
123
 *  struct vsb vsb[1];
124
 *  char *p;
125
 *
126
 *  WS_VSB_new(vsb, ctx->ws);
127
 *  VSB_printf(vsb, "blablabla");
128
 *  p = WS_VSB_finish(vsb, ctx->ws, NULL);
129
 *  if (p == NULL)
130
 *    return (FAILURE);
131
 */
132
133
void
134
WS_VSB_new(struct vsb *vsb, struct ws *ws)
135
0
{
136
0
  unsigned u;
137
0
  static char bogus[2]; // Smallest possible vsb
138
139
0
  AN(vsb);
140
0
  WS_Assert(ws);
141
0
  u = WS_ReserveAll(ws);
142
0
  if (WS_Overflowed(ws) || u < 2)
143
0
    AN(VSB_init(vsb, bogus, sizeof bogus));
144
0
  else
145
0
    AN(VSB_init(vsb, WS_Reservation(ws), u));
146
0
}
147
148
char *
149
WS_VSB_finish(struct vsb *vsb, struct ws *ws, size_t *szp)
150
0
{
151
0
  char *p;
152
153
0
  AN(vsb);
154
0
  WS_Assert(ws);
155
0
  if (!VSB_finish(vsb)) {
156
0
    p = VSB_data(vsb);
157
0
    if (p == ws->f) {
158
0
      WS_Release(ws, VSB_len(vsb) + 1);
159
0
      if (szp != NULL)
160
0
        *szp = VSB_len(vsb);
161
0
      VSB_fini(vsb);
162
0
      return (p);
163
0
    }
164
0
  }
165
0
  WS_MarkOverflow(ws);
166
0
  VSB_fini(vsb);
167
0
  WS_Release(ws, 0);
168
0
  if (szp)
169
0
    *szp = 0;
170
0
  return (NULL);
171
0
}