Fix CID 1491093: attrib leaked if attvalue is null
[claws.git] / src / plugins / litehtml_viewer / litehtml / html.cpp
blobee8ddad8dd0a5a58ffa69fc91a542de9ee243c20
1 #include "html.h"
2 #include "types.h"
3 #include "utf8_strings.h"
5 void litehtml::trim(string &s, const string& chars_to_trim)
7 string::size_type pos = s.find_first_not_of(chars_to_trim);
8 if(pos != string::npos)
10 s.erase(s.begin(), s.begin() + pos);
12 else
14 s = "";
15 return;
17 pos = s.find_last_not_of(chars_to_trim);
18 if(pos != string::npos)
20 s.erase(s.begin() + pos + 1, s.end());
24 void litehtml::lcase(string &s)
26 for(char & i : s)
28 i = t_tolower(i);
32 litehtml::string::size_type litehtml::find_close_bracket(const string &s, string::size_type off, char open_b, char close_b)
34 int cnt = 0;
35 for(string::size_type i = off; i < s.length(); i++)
37 if(s[i] == open_b)
39 cnt++;
40 } else if(s[i] == close_b)
42 cnt--;
43 if(!cnt)
45 return i;
49 return string::npos;
52 litehtml::string litehtml::index_value(int index, const string& strings, char delim)
54 std::vector<string> vals;
55 string delims;
56 delims.push_back(delim);
57 split_string(strings, vals, delims);
58 if(index >= 0 && index < vals.size())
60 return vals[index];
62 return std::to_string(index);
65 int litehtml::value_index( const string& val, const string& strings, int defValue, char delim )
67 if(val.empty() || strings.empty() || !delim)
69 return defValue;
72 int idx = 0;
73 string::size_type delim_start = 0;
74 string::size_type delim_end = strings.find(delim, delim_start);
75 string::size_type item_len;
76 while(true)
78 if(delim_end == string::npos)
80 item_len = strings.length() - delim_start;
81 } else
83 item_len = delim_end - delim_start;
85 if(item_len == val.length())
87 if(val == strings.substr(delim_start, item_len))
89 return idx;
92 idx++;
93 delim_start = delim_end;
94 if(delim_start == string::npos) break;
95 delim_start++;
96 if(delim_start == strings.length()) break;
97 delim_end = strings.find(delim, delim_start);
99 return defValue;
102 bool litehtml::value_in_list( const string& val, const string& strings, char delim )
104 int idx = value_index(val, strings, -1, delim);
105 if(idx >= 0)
107 return true;
109 return false;
112 void litehtml::split_string(const string& str, string_vector& tokens, const string& delims, const string& delims_preserve, const string& quote)
114 if(str.empty() || (delims.empty() && delims_preserve.empty()))
116 return;
119 string all_delims = delims + delims_preserve + quote;
121 string::size_type token_start = 0;
122 string::size_type token_end = str.find_first_of(all_delims, token_start);
123 string::size_type token_len;
124 string token;
125 while(true)
127 while( token_end != string::npos && quote.find_first_of(str[token_end]) != string::npos )
129 if(str[token_end] == '(')
131 token_end = find_close_bracket(str, token_end, '(', ')');
132 } else if(str[token_end] == '[')
134 token_end = find_close_bracket(str, token_end, '[', ']');
135 } else if(str[token_end] == '{')
137 token_end = find_close_bracket(str, token_end, '{', '}');
138 } else
140 token_end = str.find_first_of(str[token_end], token_end + 1);
142 if(token_end != string::npos)
144 token_end = str.find_first_of(all_delims, token_end + 1);
148 if(token_end == string::npos)
150 token_len = string::npos;
151 } else
153 token_len = token_end - token_start;
156 token = str.substr(token_start, token_len);
157 if(!token.empty())
159 tokens.push_back( token );
161 if(token_end != string::npos && !delims_preserve.empty() && delims_preserve.find_first_of(str[token_end]) != string::npos)
163 tokens.push_back( str.substr(token_end, 1) );
166 token_start = token_end;
167 if(token_start == string::npos) break;
168 token_start++;
169 if(token_start == str.length()) break;
170 token_end = str.find_first_of(all_delims, token_start);
174 void litehtml::join_string(string& str, const string_vector& tokens, const string& delims)
176 str = "";
177 for (size_t i = 0; i < tokens.size(); i++)
179 if (i != 0)
181 str += delims;
183 str += tokens[i];
187 int litehtml::t_strcasecmp(const char *s1, const char *s2)
189 int i, d, c;
191 for (i = 0;; i++)
193 c = t_tolower((unsigned char)s1[i]);
194 d = c - t_tolower((unsigned char)s2[i]);
195 if (d < 0)
196 return -1;
197 else if (d > 0)
198 return 1;
199 else if (c == 0)
200 return 0;
204 int litehtml::t_strncasecmp(const char *s1, const char *s2, size_t n)
206 int i, d, c;
208 for (i = 0; i < n; i++)
210 c = t_tolower((unsigned char)s1[i]);
211 d = c - t_tolower((unsigned char)s2[i]);
212 if (d < 0)
213 return -1;
214 else if (d > 0)
215 return 1;
216 else if (c == 0)
217 return 0;
220 return 0;
223 litehtml::string litehtml::get_escaped_string(const string& in_str)
225 string ret;
226 for (auto ch : in_str)
228 switch (ch)
230 case '\'':
231 ret += "\\'";
232 break;
234 case '\"':
235 ret += "\\\"";
236 break;
238 case '\?':
239 ret += "\\?";
240 break;
242 case '\\':
243 ret += "\\\\";
244 break;
246 case '\a':
247 ret += "\\a";
248 break;
250 case '\b':
251 ret += "\\b";
252 break;
254 case '\f':
255 ret += "\\f";
256 break;
258 case '\n':
259 ret += "\\n";
260 break;
262 case '\r':
263 ret += "\\r";
264 break;
266 case '\t':
267 ret += "\\t";
268 break;
270 case '\v':
271 ret += "\\v";
272 break;
274 default:
275 ret += ch;
278 return ret;
281 bool litehtml::is_number(const string& string, const bool allow_dot) {
282 for (auto ch : string)
284 if (!(t_isdigit(ch) || (allow_dot && ch == '.')))
286 return false;
289 return true;