Parsing.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/* DEBUG: section 03 Configuration File Parsing */
10
11#include "squid.h"
12#include "cache_cf.h"
13#include "compat/strtoll.h"
14#include "ConfigParser.h"
15#include "debug/Stream.h"
16#include "globals.h"
17#include "Parsing.h"
18#include "sbuf/Stream.h"
19
20/*
21 * These functions is the same as atoi/l/f, except that they check for errors
22 */
23
24double
25xatof(const char *token)
26{
27 char *end = nullptr;
28 double ret = strtod(token, &end);
29
30 if (ret == 0 && end == token) {
31 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: No digits were found in the input value '" << token << "'.");
33 }
34
35 if (*end) {
36 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Invalid value: '" << token << "' is supposed to be a number.");
38 }
39
40 return ret;
41}
42
43int
44xatoi(const char *token)
45{
46 int64_t input = xatoll(token, 10);
47 int ret = (int) input;
48
49 if (input != static_cast<int64_t>(ret)) {
50 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'int'.");
52 }
53
54 return ret;
55}
56
57unsigned int
58xatoui(const char *token, char eov)
59{
60 int64_t input = xatoll(token, 10, eov);
61 if (input < 0)
62 throw TextException(ToSBuf("the input value '", token, "' cannot be less than 0"), Here());
63
64 unsigned int ret = (unsigned int) input;
65 if (input != static_cast<int64_t>(ret))
66 throw TextException(ToSBuf("the value '", token, "' is larger than the type 'unsigned int'"), Here());
67
68 return ret;
69}
70
71long
72xatol(const char *token)
73{
74 int64_t input = xatoll(token, 10);
75 long ret = (long) input;
76
77 if (input != static_cast<int64_t>(ret)) {
78 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'long'.");
80 }
81
82 return ret;
83}
84
85int64_t
86xatoll(const char *token, int base, char eov)
87{
88 char *end = nullptr;
89 int64_t ret = strtoll(token, &end, base);
90
91 if (end == token) {
92 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: No digits were found in the input value '" << token << "'.");
94 }
95
96 if (*end != eov) {
97 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: Invalid value: '" << token << "' is supposed to be a number.");
99 }
100
101 return ret;
102}
103
104uint64_t
105xatoull(const char *token, int base, char eov)
106{
107 const auto number = xatoll(token, base, eov);
108 if (number < 0)
109 throw TextException(ToSBuf("the input value '", token, "' cannot be less than 0"), Here());
110 return static_cast<uint64_t>(number);
111}
112
113unsigned short
114xatos(const char *token)
115{
116 long port = xatol(token);
117
118 if (port < 0) {
119 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' cannot be less than 0.");
121 }
122
123 if (port & ~0xFFFF) {
124 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'short'.");
126 }
127
128 return port;
129}
130
131int64_t
133{
134 char *token = ConfigParser::NextToken();
135 if (!token) {
137 return -1; // not reachable
138 }
139
140 return xatoll(token, 10);
141}
142
143/*
144 * This function is different from others (e.g., GetInteger64, GetShort)
145 * because it supports octal and hexadecimal numbers
146 */
147int
149{
150 char *token = ConfigParser::NextToken();
151 int i;
152
153 if (!token) {
155 return -1; // not reachable
156 }
157
158 // The conversion must honor 0 and 0x prefixes, which are important for things like umask
159 int64_t ret = xatoll(token, 0);
160
161 i = (int) ret;
162 if (ret != static_cast<int64_t>(i)) {
163 debugs(0, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: The value '" << token << "' is larger than the type 'int'.");
165 }
166
167 return i;
168}
169
170/*
171 * This function is similar as GetInteger() but the token might contain
172 * the percentage symbol (%) and we check whether the value is in the range
173 * of [0, 100]
174 * So, we accept two types of input: 1. XX% or 2. XX , 0<=XX<=100
175 * unless the limit parameter is set to false.
176 */
177double
178GetPercentage(bool limit)
179{
180 char *token = ConfigParser::NextToken();
181
182 if (!token) {
183 debugs(3, DBG_CRITICAL, "FATAL: A percentage value is missing.");
185 return 0.0; // not reachable
186 }
187
188 //if there is a % in the end of the digits, we remove it and go on.
189 char* end = &token[strlen(token)-1];
190 if (*end == '%') {
191 *end = '\0';
192 }
193
194 int p = xatoi(token);
195
196 if (p < 0 || (limit && p > 100)) {
197 debugs(3, DBG_CRITICAL, "FATAL: The value '" << token << "' is out of range. A percentage should be within [0, 100].");
199 }
200
201 return static_cast<double>(p) / 100.0;
202}
203
204unsigned short
206{
207 char *token = ConfigParser::NextToken();
208 if (!token) {
210 return 0; // not reachable
211 }
212
213 return xatos(token);
214}
215
216bool
217StringToInt(const char *s, int &result, const char **p, int base)
218{
219 if (s) {
220 char *ptr = nullptr;
221 const int h = (int) strtol(s, &ptr, base);
222
223 if (ptr != s && ptr) {
224 result = h;
225
226 if (p)
227 *p = ptr;
228
229 return true;
230 }
231 }
232
233 return false;
234}
235
236bool
237StringToInt64(const char *s, int64_t &result, const char **p, int base)
238{
239 if (s) {
240 char *ptr = nullptr;
241 const int64_t h = (int64_t) strtoll(s, &ptr, base);
242
243 if (ptr != s && ptr) {
244 result = h;
245
246 if (p)
247 *p = ptr;
248
249 return true;
250 }
251 }
252
253 return false;
254}
255
256bool
257GetHostWithPort(char *token, Ip::Address *ipa)
258{
259 char *t;
260 char *host;
261 char *tmp;
262 unsigned short port;
263
264 host = nullptr;
265 port = 0;
266
267 if (*token == '[') {
268 /* [host]:port */
269 host = token + 1;
270 t = strchr(host, ']');
271 if (!t)
272 return false;
273 *t = '\0';
274 ++t;
275 if (*t != ':')
276 return false;
277 port = xatos(t + 1);
278 } else if ((t = strchr(token, ':'))) {
279 /* host:port */
280 host = token;
281 *t = '\0';
282 port = xatos(t + 1);
283
284 if (0 == port)
285 return false;
286 } else if (strtol(token, &tmp, 10) && !*tmp) {
287 port = xatos(token);
288 } else {
289 host = token;
290 port = 0;
291 }
292
293 if (nullptr == host)
294 ipa->setAnyAddr();
295 else if (ipa->GetHostByName(host)) /* do not use ipcache. Accept either FQDN or IPA. */
296 (void) 0;
297 else
298 return false;
299
300 /* port MUST be set after the IPA lookup/conversion is performed. */
301 ipa->port(port);
302
303 return true;
304}
305
#define Here()
source code location of the caller
Definition: Here.h:15
unsigned int xatoui(const char *token, char eov)
Definition: Parsing.cc:58
double GetPercentage(bool limit)
Definition: Parsing.cc:178
int64_t xatoll(const char *token, int base, char eov)
Definition: Parsing.cc:86
bool StringToInt64(const char *s, int64_t &result, const char **p, int base)
Definition: Parsing.cc:237
bool GetHostWithPort(char *token, Ip::Address *ipa)
Definition: Parsing.cc:257
uint64_t xatoull(const char *token, int base, char eov)
Definition: Parsing.cc:105
double xatof(const char *token)
Definition: Parsing.cc:25
unsigned short xatos(const char *token)
Definition: Parsing.cc:114
bool StringToInt(const char *s, int &result, const char **p, int base)
Definition: Parsing.cc:217
int64_t GetInteger64(void)
Definition: Parsing.cc:132
unsigned short GetShort(void)
Definition: Parsing.cc:205
int GetInteger(void)
Definition: Parsing.cc:148
long xatol(const char *token)
Definition: Parsing.cc:72
int xatoi(const char *token)
Definition: Parsing.cc:44
void self_destruct(void)
Definition: cache_cf.cc:277
static char * NextToken()
bool GetHostByName(const char *s)
Definition: Address.cc:372
void setAnyAddr()
NOTE: Does NOT clear the Port stored. Only the Address and Type.
Definition: Address.cc:177
unsigned short port() const
Definition: Address.cc:778
an std::runtime_error with thrower location info
Definition: TextException.h:21
#define DBG_PARSE_NOTE(x)
Definition: Stream.h:42
#define DBG_IMPORTANT
Definition: Stream.h:38
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:194
#define DBG_CRITICAL
Definition: Stream.h:37
static int port
Definition: ldap_backend.cc:70
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
Definition: Stream.h:63
int64_t strtoll(const char *nptr, char **endptr, int base)
Definition: strtoll.c:61
int unsigned int
Definition: stub_fd.cc:19
number
Definition: testStatHist.cc:32

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors