]>
Commit | Line | Data |
---|---|---|
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 */ | |
16 | void | |
17 | strListAdd(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 */ | |
31 | int | |
32 | strListIsMember(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 */ | |
49 | int | |
50 | strListIsSubstr(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 | */ | |
72 | int | |
73 | strListGetItem(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 |