]> git.ipfire.org Git - thirdparty/squid.git/blob - src/StrList.cc
Remove unused strnstr() replacement (#1721)
[thirdparty/squid.git] / src / StrList.cc
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 66 HTTP Header Tools */
10
11 #include "squid.h"
12 #include "base/TextException.h"
13 #include "sbuf/SBuf.h"
14 #include "SquidString.h"
15 #include "StrList.h"
16
17 void
18 strListAdd(String &str, const char *item, const size_t itemSize, const char delimiter)
19 {
20 if (str.size()) {
21 const char buf[] = { delimiter, ' ' };
22 const auto bufSize = sizeof(buf);
23 Must(str.canGrowBy(bufSize));
24 str.append(buf, bufSize);
25 }
26 Must(str.canGrowBy(itemSize));
27 str.append(item, itemSize);
28 }
29
30 void
31 strListAdd(String *str, const char *item, const char delimiter)
32 {
33 assert(str);
34 assert(item);
35 strListAdd(*str, item, strlen(item), delimiter);
36 }
37
38 void
39 strListAdd(String &str, const SBuf &item, char delimiter)
40 {
41 strListAdd(str, item.rawContent(), item.length(), delimiter);
42 }
43
44 /** returns true iff "m" is a member of the list */
45 int
46 strListIsMember(const String * list, const SBuf &m, char del)
47 {
48 const char *pos = nullptr;
49 const char *item;
50 int ilen = 0;
51
52 assert(list);
53 int mlen = m.plength();
54 while (strListGetItem(list, del, &item, &ilen, &pos)) {
55 if (mlen == ilen && m.caseCmp(item, ilen) == 0)
56 return 1;
57 }
58 return 0;
59 }
60
61 /** returns true iff "s" is a substring of a member of the list */
62 int
63 strListIsSubstr(const String * list, const char *s, char del)
64 {
65 assert(list && del);
66 return (list->find(s) != String::npos);
67 }
68
69 /**
70 * iterates through a 0-terminated string of items separated by 'del's.
71 * white space around 'del' is considered to be a part of 'del'
72 * like strtok, but preserves the source, and can iterate several strings at once
73 *
74 * returns true if next item is found.
75 * init pos with NULL to start iteration.
76 */
77 int
78 strListGetItem(const String * str, char del, const char **item, int *ilen, const char **pos)
79 {
80 size_t len;
81 /* ',' is always enabled as field delimiter as this is required for
82 * processing merged header values properly, even if Cookie normally
83 * uses ';' as delimiter.
84 */
85 static char delim[3][8] = {
86 "\"?,",
87 "\"\\",
88 " ?,\t\r\n"
89 };
90 int quoted = 0;
91 assert(str && item && pos);
92
93 delim[0][1] = del;
94 delim[2][1] = del;
95
96 if (!*pos) {
97 *pos = str->termedBuf();
98
99 if (!*pos)
100 return 0;
101 }
102
103 /* skip leading whitespace and delimiters */
104 *pos += strspn(*pos, delim[2]);
105
106 *item = *pos; /* remember item's start */
107
108 /* find next delimiter */
109 do {
110 *pos += strcspn(*pos, delim[quoted]);
111 if (**pos == '"') {
112 quoted = !quoted;
113 *pos += 1;
114 } else if (quoted && **pos == '\\') {
115 *pos += 1;
116 if (**pos)
117 *pos += 1;
118 } else {
119 break; /* Delimiter found, marking the end of this value */
120 }
121 } while (**pos);
122
123 len = *pos - *item; /* *pos points to del or '\0' */
124
125 /* rtrim */
126 while (len > 0 && xisspace((*item)[len - 1]))
127 --len;
128
129 if (ilen)
130 *ilen = len;
131
132 return len > 0;
133 }
134
135 SBuf
136 getListMember(const String &list, const char *key, const char delimiter)
137 {
138 const char *pos = nullptr;
139 const char *item = nullptr;
140 int ilen = 0;
141 const auto keyLen = strlen(key);
142 while (strListGetItem(&list, delimiter, &item, &ilen, &pos)) {
143 if (static_cast<size_t>(ilen) > keyLen && strncmp(item, key, keyLen) == 0 && item[keyLen] == '=')
144 return SBuf(item + keyLen + 1, ilen - keyLen - 1);
145 }
146 return SBuf();
147 }
148