]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/StrList.cc
2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 66 HTTP Header Tools */
12 #include "base/TextException.h"
13 #include "sbuf/SBuf.h"
14 #include "SquidString.h"
18 strListAdd(String
&str
, const char *item
, const size_t itemSize
, const char delimiter
)
21 const char buf
[] = { delimiter
, ' ' };
22 const auto bufSize
= sizeof(buf
);
23 Must(str
.canGrowBy(bufSize
));
24 str
.append(buf
, bufSize
);
26 Must(str
.canGrowBy(itemSize
));
27 str
.append(item
, itemSize
);
31 strListAdd(String
*str
, const char *item
, const char delimiter
)
35 strListAdd(*str
, item
, strlen(item
), delimiter
);
39 strListAdd(String
&str
, const SBuf
&item
, char delimiter
)
41 strListAdd(str
, item
.rawContent(), item
.length(), delimiter
);
44 /** returns true iff "m" is a member of the list */
46 strListIsMember(const String
* list
, const SBuf
&m
, char del
)
48 const char *pos
= NULL
;
53 int mlen
= m
.plength();
54 while (strListGetItem(list
, del
, &item
, &ilen
, &pos
)) {
55 if (mlen
== ilen
&& m
.caseCmp(item
, ilen
) == 0)
61 /** returns true iff "s" is a substring of a member of the list */
63 strListIsSubstr(const String
* list
, const char *s
, char del
)
66 return (list
->find(s
) != String::npos
);
69 * Note: the original code with a loop is broken because it uses strstr()
70 * instead of strnstr(). If 's' contains a 'del', strListIsSubstr() may
71 * return true when it should not. If 's' does not contain a 'del', the
72 * implementation is equavalent to strstr()! Thus, we replace the loop with
73 * strstr() above until strnstr() is available.
78 * iterates through a 0-terminated string of items separated by 'del's.
79 * white space around 'del' is considered to be a part of 'del'
80 * like strtok, but preserves the source, and can iterate several strings at once
82 * returns true if next item is found.
83 * init pos with NULL to start iteration.
86 strListGetItem(const String
* str
, char del
, const char **item
, int *ilen
, const char **pos
)
89 /* ',' is always enabled as field delimiter as this is required for
90 * processing merged header values properly, even if Cookie normally
91 * uses ';' as delimiter.
93 static char delim
[3][8] = {
99 assert(str
&& item
&& pos
);
105 *pos
= str
->termedBuf();
111 /* skip leading whitespace and delimiters */
112 *pos
+= strspn(*pos
, delim
[2]);
114 *item
= *pos
; /* remember item's start */
116 /* find next delimiter */
118 *pos
+= strcspn(*pos
, delim
[quoted
]);
122 } else if (quoted
&& **pos
== '\\') {
127 break; /* Delimiter found, marking the end of this value */
131 len
= *pos
- *item
; /* *pos points to del or '\0' */
134 while (len
> 0 && xisspace((*item
)[len
- 1]))
144 getListMember(const String
&list
, const char *key
, const char delimiter
)
146 const char *pos
= nullptr;
147 const char *item
= nullptr;
149 const auto keyLen
= strlen(key
);
150 while (strListGetItem(&list
, delimiter
, &item
, &ilen
, &pos
)) {
151 if (static_cast<size_t>(ilen
) > keyLen
&& strncmp(item
, key
, keyLen
) == 0 && item
[keyLen
] == '=')
152 return SBuf(item
+ keyLen
+ 1, ilen
- keyLen
- 1);