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