]> git.ipfire.org Git - thirdparty/squid.git/blame - src/StrList.cc
Prep for 3.3.12 and 3.4.4
[thirdparty/squid.git] / src / StrList.cc
CommitLineData
28204b3b
FC
1/*
2 * DEBUG: section 66 HTTP Header Tools
3 * AUTHOR: Alex Rousskov
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.
21 *
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.
26 *
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
33#include "squid.h"
34#include "SquidString.h"
35#include "StrList.h"
36
37/** appends an item to the list */
38void
39strListAdd(String * str, const char *item, char del)
40{
41 assert(str && item);
42 if (str->size()) {
43 char buf[3];
44 buf[0] = del;
45 buf[1] = ' ';
46 buf[2] = '\0';
47 str->append(buf, 2);
48 }
49 str->append(item, strlen(item));
50}
51
52/** returns true iff "m" is a member of the list */
53int
54strListIsMember(const String * list, const char *m, char del)
55{
56 const char *pos = NULL;
57 const char *item;
58 int ilen = 0;
59 int mlen;
60
61 assert(list && m);
62 mlen = strlen(m);
63 while (strListGetItem(list, del, &item, &ilen, &pos)) {
64 if (mlen == ilen && !strncasecmp(item, m, ilen))
65 return 1;
66 }
67 return 0;
68}
69
70/** returns true iff "s" is a substring of a member of the list */
71int
72strListIsSubstr(const String * list, const char *s, char del)
73{
74 assert(list && del);
75 return (list->find(s) != String::npos);
76
77 /** \note
78 * Note: the original code with a loop is broken because it uses strstr()
79 * instead of strnstr(). If 's' contains a 'del', strListIsSubstr() may
80 * return true when it should not. If 's' does not contain a 'del', the
81 * implementaion is equavalent to strstr()! Thus, we replace the loop with
82 * strstr() above until strnstr() is available.
83 */
84}
85
86/**
87 * iterates through a 0-terminated string of items separated by 'del's.
88 * white space around 'del' is considered to be a part of 'del'
89 * like strtok, but preserves the source, and can iterate several strings at once
90 *
91 * returns true if next item is found.
92 * init pos with NULL to start iteration.
93 */
94int
95strListGetItem(const String * str, char del, const char **item, int *ilen, const char **pos)
96{
97 size_t len;
98 /* ',' is always enabled as field delimiter as this is required for
99 * processing merged header values properly, even if Cookie normally
100 * uses ';' as delimiter.
101 */
102 static char delim[3][8] = {
103 "\"?,",
104 "\"\\",
105 " ?,\t\r\n"
106 };
107 int quoted = 0;
108 assert(str && item && pos);
109
110 delim[0][1] = del;
111 delim[2][1] = del;
112
113 if (!*pos) {
114 *pos = str->termedBuf();
115
116 if (!*pos)
117 return 0;
118 }
119
120 /* skip leading whitespace and delimiters */
121 *pos += strspn(*pos, delim[2]);
122
123 *item = *pos; /* remember item's start */
124
125 /* find next delimiter */
126 do {
127 *pos += strcspn(*pos, delim[quoted]);
128 if (**pos == '"') {
129 quoted = !quoted;
130 *pos += 1;
131 } else if (quoted && **pos == '\\') {
132 *pos += 1;
133 if (**pos)
134 *pos += 1;
135 } else {
136 break; /* Delimiter found, marking the end of this value */
137 }
138 } while (**pos);
139
140 len = *pos - *item; /* *pos points to del or '\0' */
141
142 /* rtrim */
143 while (len > 0 && xisspace((*item)[len - 1]))
144 --len;
145
146 if (ilen)
147 *ilen = len;
148
149 return len > 0;
150}
151