Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: compiled/subscription/DownloadableSubscription.cpp

Issue 29606600: Issue 5146 - Implement DownloadableSubscription parsing in C++ (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Removed Md5sum and associated code Created Aug. 14, 2018, 12:38 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « compiled/subscription/DownloadableSubscription.h ('k') | compiled/subscription/Subscription.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #include <cwctype>
19 #include <limits>
20
18 #include "DownloadableSubscription.h" 21 #include "DownloadableSubscription.h"
22 #include "../FilterNotifier.h"
23 #include "../StringScanner.h"
24 #include "../filter/CommentFilter.h"
25
26 ABP_NS_USING
27
28 namespace {
29 constexpr int MILLIS_IN_HOUR = 60 * 60 * 1000;
30 constexpr int MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR;
31 // limits
32 constexpr int64_t MAX_HOUR = std::numeric_limits<int64_t>::max() / MILLIS_IN_H OUR;
33 constexpr int64_t MAX_DAY = std::numeric_limits<int64_t>::max() / MILLIS_IN_DA Y;
34
35 typedef std::pair<DependentString, DependentString> Param;
36
37 Param ParseParam(const String& text)
38 {
39 Param param;
40
41 if (text[0] == u'!')
42 {
43 bool foundColon = false;
44 String::size_type beginParam = 0;
45 String::size_type endParam = 0;
46 String::size_type beginValue = 0;
47 for (String::size_type i = 1; i < text.length(); i++)
48 {
49 switch (text[i])
50 {
51 case ' ':
52 case '\t':
53 if (beginParam > 0 && !foundColon)
54 {
55 endParam = i;
56 }
57 break;
58 case ':':
59 foundColon = true;
60 endParam = i;
61 break;
62 default:
63 if (foundColon)
64 {
65 beginValue = i;
66 }
67 else
68 {
69 if (beginParam == 0)
70 beginParam = i;
71 }
72 break;
73 }
74 if (beginValue > 0)
75 break;
76 }
77 if (beginValue > 0)
78 {
79 param.first = DependentString(text, beginParam, endParam - beginParam);
80 param.first.toLower();
81 param.second = DependentString(
82 text, beginValue, text.length() - beginValue);
83 }
84 }
85 return param;
86 }
87 }
88
89 DownloadableSubscription_Parser::DownloadableSubscription_Parser()
90 : mFirstLine(true)
91 {
92 annotate_address(this, "DownloadableSubscription_Parser");
93 }
94
95 namespace {
96 const DependentString ADBLOCK_HEADER(u"[Adblock"_str);
97 }
98
99 void DownloadableSubscription_Parser::Process(const String& line)
100 {
101 bool isHeader = false;
102 isHeader = line.find(ADBLOCK_HEADER) != String::npos;
103 if (!isHeader)
104 {
105 auto param = ParseParam(line);
106 if (param.first.is_invalid())
107 mFiltersText.emplace_back(line);
108 else
109 mParams[param.first] = param.second;
110 }
111 }
112
113 int64_t DownloadableSubscription_Parser::ParseExpires(const String& expires)
114 {
115 bool isHour = false;
116 StringScanner scanner(expires);
117 String::size_type numStart = 0;
118 String::size_type numLen = 0;
119 while(!scanner.done())
120 {
121 auto ch = scanner.next();
122 if (std::iswdigit(ch))
123 {
124 if (numLen == 0)
125 numStart = scanner.position();
126 numLen++;
127 }
128 else if (std::iswspace(ch))
129 {
130 if (numLen)
131 break;
132 }
133 else
134 {
135 if (numLen)
136 scanner.back();
137 break;
138 }
139 }
140
141 DependentString numStr(expires, numStart, numLen);
142 int64_t num = lexical_cast<int64_t>(numStr);
143 if (num == 0)
144 return 0;
145
146 while (!scanner.done())
147 {
148 auto ch = scanner.next();
149 if (std::iswspace(ch))
150 continue;
151
152 if (ch == u'h')
153 isHour = true;
154
155 // assume we are done here. The rest is ignored.
156 break;
157 }
158 // check for overflow.
159 if ((isHour && (num > MAX_HOUR)) || (num > MAX_DAY))
160 return 0;
161
162 num *= isHour ? MILLIS_IN_HOUR : MILLIS_IN_DAY;
163 return num;
164 }
165
166 int64_t DownloadableSubscription_Parser::Finalize(DownloadableSubscription& subs cription)
167 {
168 auto entry = mParams.find(u"title"_str);
169 if (entry)
170 {
171 subscription.SetTitle(entry->second);
172 subscription.SetFixedTitle(true);
173 }
174 else
175 subscription.SetFixedTitle(false);
176
177 int32_t version = 0;
178 entry = mParams.find(u"version"_str);
179 if (entry)
180 version = lexical_cast<int32_t>(entry->second);
181 subscription.SetDataRevision(version);
182
183 int64_t expires = 0;
184 entry = mParams.find(u"expires"_str);
185 if (entry)
186 expires = ParseExpires(entry->second);
187
188 FilterNotifier::SubscriptionChange(
189 FilterNotifier::Topic::SUBSCRIPTION_BEFORE_FILTERS_REPLACED,
190 subscription);
191
192 Subscription::Filters filters;
193 filters.reserve(mFiltersText.size());
194 for (auto text : mFiltersText)
195 {
196 DependentString dependent(text);
197 filters.emplace_back(Filter::FromText(dependent), false);
198 }
199
200 subscription.SetFilters(std::move(filters));
201 FilterNotifier::SubscriptionChange(
202 FilterNotifier::Topic::SUBSCRIPTION_FILTERS_REPLACED, subscription);
203
204 return expires;
205 }
206
207 namespace {
208 DependentString emptyString = u""_str;
209 }
210
211 const String& DownloadableSubscription_Parser::GetRedirect() const
212 {
213 auto entry = mParams.find(u"redirect"_str);
214 if (entry)
215 return entry->second;
216 return emptyString;
217 }
218
219 const String& DownloadableSubscription_Parser::GetHomepage() const
220 {
221 auto entry = mParams.find(u"homepage"_str);
222 if (entry)
223 return entry->second;
224 return emptyString;
225 }
19 226
20 ABP_NS_USING 227 ABP_NS_USING
21 228
22 DownloadableSubscription::DownloadableSubscription(const String& id) 229 DownloadableSubscription::DownloadableSubscription(const String& id)
23 : Subscription(classType, id), mFixedTitle(false), mLastCheck(0), 230 : Subscription(classType, id), mFixedTitle(false), mLastCheck(0),
24 mHardExpiration(0), mSoftExpiration(0), mLastDownload(0), mLastSuccess(0), 231 mHardExpiration(0), mSoftExpiration(0), mLastDownload(0), mLastSuccess(0),
25 mErrorCount(0), mDataRevision(0), mDownloadCount(0) 232 mErrorCount(0), mDataRevision(0), mDownloadCount(0)
26 { 233 {
27 SetTitle(id); 234 SetTitle(id);
28 } 235 }
29 236
237 DownloadableSubscription_Parser* DownloadableSubscription::ParseDownload()
238 {
239 return new DownloadableSubscription_Parser();
240 }
241
30 OwnedString DownloadableSubscription::Serialize() const 242 OwnedString DownloadableSubscription::Serialize() const
31 { 243 {
32 OwnedString result(Subscription::Serialize()); 244 OwnedString result(Subscription::Serialize());
33 if (mFixedTitle) 245 if (mFixedTitle)
34 result.append(ABP_TEXT("fixedTitle=true\n"_str)); 246 result.append(ABP_TEXT("fixedTitle=true\n"_str));
35 if (!mHomepage.empty()) 247 if (!mHomepage.empty())
36 { 248 {
37 result.append(ABP_TEXT("homepage="_str)); 249 result.append(ABP_TEXT("homepage="_str));
38 result.append(mHomepage); 250 result.append(mHomepage);
39 result.append(ABP_TEXT('\n')); 251 result.append(ABP_TEXT('\n'));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 result.append(ABP_TEXT('\n')); 305 result.append(ABP_TEXT('\n'));
94 } 306 }
95 if (mDownloadCount) 307 if (mDownloadCount)
96 { 308 {
97 result.append(ABP_TEXT("downloadCount="_str)); 309 result.append(ABP_TEXT("downloadCount="_str));
98 result.append(mDownloadCount); 310 result.append(mDownloadCount);
99 result.append(ABP_TEXT('\n')); 311 result.append(ABP_TEXT('\n'));
100 } 312 }
101 return result; 313 return result;
102 } 314 }
OLDNEW
« no previous file with comments | « compiled/subscription/DownloadableSubscription.h ('k') | compiled/subscription/Subscription.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld