]> git.ipfire.org Git - thirdparty/squid.git/blame - src/Parsing.cc
Fix parsing of max-stale values in Surrogate-Control header
[thirdparty/squid.git] / src / Parsing.cc
CommitLineData
c8f4eac4 1/*
b510f3a1 2 * DEBUG: section 03 Configuration File Parsing
c8f4eac4 3 * AUTHOR: Harvest Derived
4 *
5 * SQUID Web Proxy Cache http://www.squid-cache.org/
6 * ----------------------------------------------------------
7 *
8 * Squid is the result of efforts by numerous individuals from
9 * the Internet community; see the CONTRIBUTORS file for full
10 * details. Many organizations have provided support for Squid's
11 * development; see the SPONSORS file for full details. Squid is
12 * Copyrighted (C) 2001 by the Regents of the University of
13 * California; see the COPYRIGHT file for full details. Squid
14 * incorporates software developed and/or copyrighted by other
15 * sources; see the CREDITS file for full details.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
26ac0430 21 *
c8f4eac4 22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26ac0430 26 *
c8f4eac4 27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
30 *
31 */
32
f7f3304a 33#include "squid.h"
8a01b99e 34#include "cache_cf.h"
27bc2077 35#include "compat/strtoll.h"
c8f4eac4 36#include "Parsing.h"
54a063a2
TX
37#include "globals.h"
38#include "Debug.h"
c8f4eac4 39
40/*
41 * These functions is the same as atoi/l/f, except that they check for errors
42 */
43
0e656b69 44double
45xatof(const char *token)
c8f4eac4 46{
54a063a2 47 char *end = NULL;
0e656b69 48 double ret = strtod(token, &end);
c8f4eac4 49
54a063a2
TX
50 if (ret == 0 && end == token) {
51 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: No digits were found in the input value '" << token << "'.");
c8f4eac4 52 self_destruct();
54a063a2
TX
53 }
54
55 if (*end) {
56 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Invalid value: '" << token << "' is supposed to be a number.");
57 self_destruct();
58 }
c8f4eac4 59
60 return ret;
61}
62
63int
64xatoi(const char *token)
65{
54a063a2
TX
66 int64_t input = xatoll(token, 10);
67 int ret = (int) input;
68
69 if (input != static_cast<int64_t>(ret)) {
70 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'int'.");
71 self_destruct();
72 }
73
74 return ret;
75}
76
77unsigned int
78xatoui(const char *token)
79{
80 int64_t input = xatoll(token, 10);
81 if (input < 0) {
82 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The input value '" << token << "' cannot be less than 0.");
83 self_destruct();
84 }
85
86 unsigned int ret = (unsigned int) input;
87 if (input != static_cast<int64_t>(ret)) {
88 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'unsigned int'.");
89 self_destruct();
90 }
91
92 return ret;
c8f4eac4 93}
94
0e656b69 95long
96xatol(const char *token)
97{
54a063a2
TX
98 int64_t input = xatoll(token, 10);
99 long ret = (long) input;
100
101 if (input != static_cast<int64_t>(ret)) {
102 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'long'.");
103 self_destruct();
104 }
105
106 return ret;
107}
108
109int64_t
110xatoll(const char *token, int base)
111{
112 char *end = NULL;
113 int64_t ret = strtoll(token, &end, base);
0e656b69 114
54a063a2
TX
115 if (end == token) {
116 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: No digits were found in the input value '" << token << "'.");
0e656b69 117 self_destruct();
54a063a2
TX
118 }
119
120 if (*end) {
121 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Invalid value: '" << token << "' is supposed to be a number.");
122 self_destruct();
123 }
0e656b69 124
125 return ret;
126}
127
128unsigned short
129xatos(const char *token)
130{
131 long port = xatol(token);
132
54a063a2
TX
133 if (port < 0) {
134 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' cannot be less than 0.");
135 self_destruct();
136 }
137
138 if (port & ~0xFFFF) {
139 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'short'.");
0e656b69 140 self_destruct();
54a063a2 141 }
0e656b69 142
143 return port;
144}
145
b1fb3348
AJ
146int64_t
147GetInteger64(void)
148{
149 char *token = strtok(NULL, w_space);
b1fb3348
AJ
150
151 if (token == NULL)
152 self_destruct();
153
54a063a2 154 return xatoll(token, 10);
b1fb3348
AJ
155}
156
54a063a2
TX
157/*
158 * This function is different from others (e.g., GetInteger64, GetShort)
159 * because it supports octal and hexadecimal numbers
160 */
c8f4eac4 161int
162GetInteger(void)
163{
164 char *token = strtok(NULL, w_space);
165 int i;
166
167 if (token == NULL)
168 self_destruct();
169
54a063a2
TX
170 // The conversion must honor 0 and 0x prefixes, which are important for things like umask
171 int64_t ret = xatoll(token, 0);
172
173 i = (int) ret;
174 if (ret != static_cast<int64_t>(i)) {
175 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'int'.");
c8f4eac4 176 self_destruct();
54a063a2 177 }
c8f4eac4 178
179 return i;
180}
181
54a063a2
TX
182/*
183 * This function is similar as GetInteger() but the token might contain
184 * the percentage symbol (%) and we check whether the value is in the range
185 * of [0, 100]
186 * So, we accept two types of input: 1. XX% or 2. XX , 0<=XX<=100
187 */
188int
189GetPercentage(void)
190{
191 int p;
192 char *token = strtok(NULL, w_space);
193
194 //if there is a % in the end of the digits, we remove it and go on.
195 char* end = &token[strlen(token)-1];
196 if (*end == '%') {
197 *end = '\0';
198 }
199
200 p = xatoi(token);
201
202 if (p < 0 || p > 100) {
203 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is out of range. A percentage should be within [0, 100].");
204 self_destruct();
205 }
206
207 return p;
208}
209
f45dd259 210unsigned short
0e656b69 211GetShort(void)
212{
213 char *token = strtok(NULL, w_space);
214
215 if (token == NULL)
216 self_destruct();
217
218 return xatos(token);
219}
220
053b1f59 221bool
222StringToInt(const char *s, int &result, const char **p, int base)
223{
224 if (s) {
225 char *ptr = 0;
226 const int h = (int) strtol(s, &ptr, base);
227
228 if (ptr != s && ptr) {
229 result = h;
230
231 if (p)
232 *p = ptr;
233
234 return true;
235 }
236 }
237
238 return false;
239}
47f6e231 240
241bool
242StringToInt64(const char *s, int64_t &result, const char **p, int base)
243{
244 if (s) {
245 char *ptr = 0;
246 const int64_t h = (int64_t) strtoll(s, &ptr, base);
247
248 if (ptr != s && ptr) {
249 result = h;
250
251 if (p)
252 *p = ptr;
253
254 return true;
255 }
256 }
257
258 return false;
259}
82b7abe3
AJ
260
261bool
b7ac5457 262GetHostWithPort(char *token, Ip::Address *ipa)
82b7abe3
AJ
263{
264 char *t;
265 char *host;
266 char *tmp;
267 unsigned short port;
268
269 host = NULL;
270 port = 0;
271
82b7abe3
AJ
272 if (*token == '[') {
273 /* [host]:port */
274 host = token + 1;
275 t = strchr(host, ']');
276 if (!t)
277 return false;
f412b2d6
FC
278 *t = '\0';
279 ++t;
82b7abe3
AJ
280 if (*t != ':')
281 return false;
282 port = xatos(t + 1);
055421ee
AJ
283 } else if ((t = strchr(token, ':'))) {
284 /* host:port */
285 host = token;
286 *t = '\0';
287 port = xatos(t + 1);
288
289 if (0 == port)
290 return false;
54a063a2
TX
291 } else if (strtol(token, &tmp, 10) && !*tmp) {
292 port = xatos(token);
055421ee
AJ
293 } else {
294 host = token;
295 port = 0;
296 }
82b7abe3
AJ
297
298 if (NULL == host)
299 ipa->SetAnyAddr();
300 else if ( ipa->GetHostByName(host) ) /* dont use ipcache. Accept either FQDN or IPA. */
301 (void) 0;
302 else
303 return false;
304
305 /* port MUST be set after the IPA lookup/conversion is performed. */
306 ipa->SetPort(port);
307
308 return true;
309}