OLD | NEW |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-present eyeo GmbH | 3 * Copyright (C) 2006-present eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 param.first.toLower(); | 80 param.first.toLower(); |
81 param.second = DependentString( | 81 param.second = DependentString( |
82 text, beginValue, text.length() - beginValue); | 82 text, beginValue, text.length() - beginValue); |
83 } | 83 } |
84 } | 84 } |
85 return param; | 85 return param; |
86 } | 86 } |
87 } | 87 } |
88 | 88 |
89 DownloadableSubscription_Parser::DownloadableSubscription_Parser() | 89 DownloadableSubscription_Parser::DownloadableSubscription_Parser() |
90 : mFirstLine(true) | |
91 { | 90 { |
92 annotate_address(this, "DownloadableSubscription_Parser"); | 91 annotate_address(this, "DownloadableSubscription_Parser"); |
93 } | 92 } |
94 | 93 |
95 namespace { | 94 namespace { |
96 const DependentString ADBLOCK_HEADER(u"[Adblock"_str); | 95 const DependentString ADBLOCK_HEADER(u"[Adblock"_str); |
| 96 const DependentString ADBLOCK_PLUS_EXTRA_HEADER(u"Plus"_str); |
| 97 |
| 98 const DependentString ERROR_INVALID_DATA(u"synchronize_invalid_data"_str); |
97 } | 99 } |
98 | 100 |
99 void DownloadableSubscription_Parser::Process(const String& line) | 101 /// Return true if more line expected. |
| 102 bool DownloadableSubscription_Parser::GetNextLine(DependentString& buffer, Depen
dentString& line) |
100 { | 103 { |
101 bool isHeader = false; | 104 StringScanner scanner(buffer); |
102 isHeader = line.find(ADBLOCK_HEADER) != String::npos; | 105 String::value_type ch = 0; |
103 if (!isHeader) | 106 while (ch != u'\r' && ch != u'\n') |
104 { | 107 { |
105 auto param = ParseParam(line); | 108 ch = scanner.next(); |
106 if (param.first.is_invalid()) | 109 if (ch == 0) |
| 110 break; |
| 111 } |
| 112 |
| 113 auto eol = scanner.position(); |
| 114 line.reset(buffer, 0, eol); |
| 115 if (eol == 0 || ch == 0) |
| 116 return false; |
| 117 while (scanner.skipOne(u'\r') || scanner.skipOne(u'\n')) |
| 118 ; |
| 119 buffer.reset(buffer, scanner.position() + 1); |
| 120 return true; |
| 121 } |
| 122 |
| 123 bool DownloadableSubscription_Parser::Process(const String& buffer) |
| 124 { |
| 125 DependentString currentBuffer(buffer); |
| 126 bool firstLine = true; |
| 127 |
| 128 DependentString line; |
| 129 while (true) |
| 130 { |
| 131 bool more = GetNextLine(currentBuffer, line); |
| 132 if (firstLine) |
| 133 { |
| 134 if (!ProcessFirstLine(line)) |
| 135 { |
| 136 mError = ERROR_INVALID_DATA; |
| 137 return false; |
| 138 } |
| 139 firstLine = false; |
| 140 } |
| 141 else |
| 142 ProcessLine(line); |
| 143 if (!more) |
| 144 break; |
| 145 } |
| 146 return true; |
| 147 } |
| 148 |
| 149 bool DownloadableSubscription_Parser::ProcessFirstLine(const String& line) |
| 150 { |
| 151 auto index = line.find(ADBLOCK_HEADER); |
| 152 if (index == String::npos) |
| 153 return false; |
| 154 |
| 155 DependentString minVersion; |
| 156 DependentString current(line, index + ADBLOCK_HEADER.length()); |
| 157 StringScanner scanner(current); |
| 158 if (scanner.skipWhiteSpace() && scanner.skipString(ADBLOCK_PLUS_EXTRA_HEADER)) |
| 159 scanner.skipWhiteSpace(); |
| 160 index = scanner.position() + 1; |
| 161 String::value_type ch = u'\0'; |
| 162 while((ch = scanner.next()) && (ch == u'.' || std::iswdigit(ch))) |
| 163 ; |
| 164 if (ch) |
| 165 scanner.back(); |
| 166 if (scanner.position() + 1 > index) |
| 167 minVersion.reset(current, index, scanner.position() + 1 - index); |
| 168 |
| 169 if (ch != u']') |
| 170 return false; |
| 171 |
| 172 mRequiredVersion = minVersion; |
| 173 return true; |
| 174 } |
| 175 |
| 176 void DownloadableSubscription_Parser::ProcessLine(const String& line) |
| 177 { |
| 178 auto param = ParseParam(line); |
| 179 if (param.first.is_invalid()) |
| 180 { |
| 181 if (!line.empty()) |
107 mFiltersText.emplace_back(line); | 182 mFiltersText.emplace_back(line); |
108 else | |
109 mParams[param.first] = param.second; | |
110 } | 183 } |
| 184 else |
| 185 mParams[param.first] = param.second; |
111 } | 186 } |
112 | 187 |
113 int64_t DownloadableSubscription_Parser::ParseExpires(const String& expires) | 188 int64_t DownloadableSubscription_Parser::ParseExpires(const String& expires) |
114 { | 189 { |
115 bool isHour = false; | 190 bool isHour = false; |
116 StringScanner scanner(expires); | 191 StringScanner scanner(expires); |
117 String::size_type numStart = 0; | 192 String::size_type numStart = 0; |
118 String::size_type numLen = 0; | 193 String::size_type numLen = 0; |
119 while(!scanner.done()) | 194 while(!scanner.done()) |
120 { | 195 { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 // check for overflow. | 233 // check for overflow. |
159 if ((isHour && (num > MAX_HOUR)) || (num > MAX_DAY)) | 234 if ((isHour && (num > MAX_HOUR)) || (num > MAX_DAY)) |
160 return 0; | 235 return 0; |
161 | 236 |
162 num *= isHour ? MILLIS_IN_HOUR : MILLIS_IN_DAY; | 237 num *= isHour ? MILLIS_IN_HOUR : MILLIS_IN_DAY; |
163 return num; | 238 return num; |
164 } | 239 } |
165 | 240 |
166 int64_t DownloadableSubscription_Parser::Finalize(DownloadableSubscription& subs
cription) | 241 int64_t DownloadableSubscription_Parser::Finalize(DownloadableSubscription& subs
cription) |
167 { | 242 { |
| 243 FilterNotifier::SubscriptionChange( |
| 244 FilterNotifier::Topic::SUBSCRIPTION_BEFORE_FILTERS_REPLACED, |
| 245 subscription); |
| 246 |
| 247 if (!mRequiredVersion.empty()) |
| 248 subscription.SetRequiredVersion(mRequiredVersion); |
| 249 |
168 auto entry = mParams.find(u"title"_str); | 250 auto entry = mParams.find(u"title"_str); |
169 if (entry) | 251 if (entry) |
170 { | 252 { |
171 subscription.SetTitle(entry->second); | 253 subscription.SetTitle(entry->second); |
172 subscription.SetFixedTitle(true); | 254 subscription.SetFixedTitle(true); |
173 } | 255 } |
174 else | 256 else |
175 subscription.SetFixedTitle(false); | 257 subscription.SetFixedTitle(false); |
176 | 258 |
177 int32_t version = 0; | 259 int32_t version = 0; |
178 entry = mParams.find(u"version"_str); | 260 entry = mParams.find(u"version"_str); |
179 if (entry) | 261 if (entry) |
180 version = lexical_cast<int32_t>(entry->second); | 262 version = lexical_cast<int32_t>(entry->second); |
181 subscription.SetDataRevision(version); | 263 subscription.SetDataRevision(version); |
182 | 264 |
183 int64_t expires = 0; | 265 int64_t expires = 0; |
184 entry = mParams.find(u"expires"_str); | 266 entry = mParams.find(u"expires"_str); |
185 if (entry) | 267 if (entry) |
186 expires = ParseExpires(entry->second); | 268 expires = ParseExpires(entry->second); |
187 | 269 |
188 FilterNotifier::SubscriptionChange( | |
189 FilterNotifier::Topic::SUBSCRIPTION_BEFORE_FILTERS_REPLACED, | |
190 subscription); | |
191 | |
192 Subscription::Filters filters; | 270 Subscription::Filters filters; |
193 filters.reserve(mFiltersText.size()); | 271 filters.reserve(mFiltersText.size()); |
194 for (auto text : mFiltersText) | 272 for (auto text : mFiltersText) |
195 { | 273 { |
196 DependentString dependent(text); | 274 DependentString dependent(text); |
197 filters.emplace_back(Filter::FromText(dependent), false); | 275 filters.emplace_back(Filter::FromText(dependent), false); |
198 } | 276 } |
199 | 277 |
200 subscription.SetFilters(std::move(filters)); | 278 subscription.SetFilters(std::move(filters)); |
201 FilterNotifier::SubscriptionChange( | 279 FilterNotifier::SubscriptionChange( |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 result.append(ABP_TEXT('\n')); | 383 result.append(ABP_TEXT('\n')); |
306 } | 384 } |
307 if (mDownloadCount) | 385 if (mDownloadCount) |
308 { | 386 { |
309 result.append(ABP_TEXT("downloadCount="_str)); | 387 result.append(ABP_TEXT("downloadCount="_str)); |
310 result.append(mDownloadCount); | 388 result.append(mDownloadCount); |
311 result.append(ABP_TEXT('\n')); | 389 result.append(ABP_TEXT('\n')); |
312 } | 390 } |
313 return result; | 391 return result; |
314 } | 392 } |
OLD | NEW |