Пример #1
0
	void INIParser::process(const wstring& line, bool eof)
	{
		static const RegExp re1 = L"/^(\\w+)=(.*)$/";
		static const RegExp re2 = L"/^\\s*\\[(.+)\\]\\s*$/";
		static const RegExp re3 = L"/\\\\\\[/g";

		static const wstring strDisabled = L"disabled";
		static const wstring strTrue = L"true";
		static const wstring strLeftBracket = L"[";

		RegExpMatch* match = NULL;
		if (wantObj && (match = re1.exec(line)))
		{
			curObj[match->substrings[1]] = match->substrings[2];
			delete match;
		}
		else if (eof || (match = re2.exec(line)))
		{
			wstring strSection;
			if (match)
			{
				strSection = toLowerCase(match->substrings[1]);
				delete match;
			}
			if (wantObj ? curObj.size() : curList.size())
			{
				// Process current object before going to next section
				switch (curSection)
				{
				case FILTER:
				case PATTERN:
					// create the filter, with certain properties set up
					// do not insert it into the filters set
					// if it's active, it'll be inserted in some subscription we'll later parse
					persistedFilters.insert(Filter::fromObject(curObj));
					break;
				case SUBSCRIPTION:
					// not supported, just record whether the whole subscription is disabled or not
					{
						auto iter = curObj.find(strDisabled);
						subscriptionDisabled =
							iter != curObj.end() && iter->second == strTrue;
					}
					break;
				case SUBSCRIPTION_FILTERS:
				case SUBSCRIPTION_PATTERNS:
				case USER_PATTERNS:
					if (!subscriptionDisabled)
					{
						for (size_t i = 0; i < curList.size(); i++)
						{
							const wstring& text = curList[i];
							Filter* filter = Filter::fromText(text);
							// need to reset the disabled property since we don't clear
							// the global filter list between reloads
							ActiveFilter* activeFilter = filter->toActiveFilter();
							if (activeFilter)
							{
								// Only reset disabled property for those not persisted yet
								if (persistedFilters.find(filter) == persistedFilters.end())
									activeFilter->setDisabled(false);
								// just put the filter in INIParser::filters
								filters.insert(activeFilter);
							}
						}
					}
				}
			}

			if (eof) return;

			auto iter = sectionMapper.find(strSection);
			if (iter != sectionMapper.end())
			{
				curSection = iter->second;
				switch (curSection)
				{
				case FILTER:
				case PATTERN:
				case SUBSCRIPTION:
					wantObj = true;
					curObj.clear();
					break;
				case SUBSCRIPTION_FILTERS:
				case SUBSCRIPTION_PATTERNS:
				case USER_PATTERNS:
				default:
					wantObj = false;
					curList.clear();
				}
			}
		}
		else if (!wantObj && line.length())
		{
			curList.push_back(replace(line, re3, strLeftBracket));
		}
	}
Пример #2
0
unsigned int AdBlockPlus::asyncLoader(void* ppathname)
{
	wstring* pstr = reinterpret_cast<wstring*>(ppathname);
	wstring pathname = *pstr;
	delete pstr;

	bool loaded = false;

	// then load stuff
	CFile file;
	if (file.Open(pathname.c_str(), CFile::modeRead | CFile::shareDenyWrite))
	{
		wstring content;
		bool success = Utils::File::readFile(file, content);
		file.Close();
		if (success)
		{
			WriterLock wl(s_mutex);
			clearFiltersInternal(true);

			INIParser parser;
			
			// split content into lines, process with INIParser one by one
			size_t lastPos = 0;
			wchar_t lastCh = 0;
			for (size_t i = 0; i < content.length(); i++)
			{
				wchar_t ch = content[i];
				// accept CR, LF and CRLF sequence
				if (ch == L'\r' || (ch == L'\n' && lastCh != L'\r'))
				{
					parser.process(content.substr(lastPos, i - lastPos), false);
				}
				if (ch == L'\r' || ch == L'\n')
					lastPos = i + 1;
				lastCh = ch;
			}
			if (lastPos < content.length())
				parser.process(content.substr(lastPos, content.length() - lastPos), false);
			parser.process(L"", true);

			// put everything in INIParser::filters into the matcher
			for (auto iter = parser.filters.begin(); iter != parser.filters.end(); ++iter)
			{
				ActiveFilter* filter = *iter;
				if (!filter || filter->isDisabled()) continue;

				RegExpFilter* regexpFilter = filter->toRegExpFilter();
				if (regexpFilter)
				{
					regexpMatcher.add(regexpFilter);
					continue;
				}

				ElemHideFilter* elemhideFilter = filter->toElemHideFilter();
				if (elemhideFilter)
					elemhideMatcher.add(elemhideFilter);
			}
			// generate the general filter list for elemhideMatcher to improve speed
			elemhideMatcher.generateGeneralFilters();
			loaded = true;
		}
	}

	// Notify main thread about load completion
	CIEHostWindow* pWindow = CIEHostWindow::GetAnyUtilsWindow();
	if (pWindow)
		pWindow->RunAsync([=]
		{
			filterLoadedCallback(loaded);
			pWindow->SendMessage(UserMessage::WM_USER_MESSAGE,
				loaded ? UserMessage::WPARAM_ABP_FILTER_LOADED : UserMessage::WPARAM_ABP_LOAD_FAILURE, 0);
		});
	else
		filterLoadedCallback(loaded);

	return 0;
}
Пример #3
0
unsigned int AdBlockPlus::asyncLoader(void* vpparam)
{
	AsyncLoaderParam* pparam = reinterpret_cast<AsyncLoaderParam*>(vpparam);
	wstring pathname = std::move(pparam->pathname);
	wstring additionalFilters = std::move(pparam->additionalFilters);
	unordered_map<wstring, wstring> options = std::move(pparam->options);
	delete pparam;

	bool loaded = false;

	// then load stuff
	CFile file;
	if (file.Open(pathname.c_str(), CFile::modeRead | CFile::shareDenyWrite))
	{
		wstring content;
		bool success = Utils::File::readFile(file, content);
		file.Close();
		if (success)
		{
			WriterLock wl(s_mutex);
			clearFiltersInternal(true);

			INIParser parser(options);
			loadContent(parser, content);
			loadContent(parser, additionalFilters);

			// put everything in INIParser::filters into the matcher
			for (auto iter = parser.filters.begin(); iter != parser.filters.end(); ++iter)
			{
				ActiveFilter* filter = *iter;
				if (!filter || filter->isDisabled()) continue;

				RegExpFilter* regexpFilter = filter->toRegExpFilter();
				if (regexpFilter)
				{
					regexpMatcher.add(regexpFilter);
					continue;
				}

				ElemHideFilter* elemhideFilter = filter->toElemHideFilter();
				if (elemhideFilter)
					elemhideMatcher.add(elemhideFilter);
			}
			// generate the general filter list for elemhideMatcher to improve speed
			elemhideMatcher.generateGeneralFilters();
			loaded = true;
		}
	}

	// Notify main thread about load completion
	CIEHostWindow* pWindow = CIEHostWindow::GetAnyUtilsWindow();
	if (pWindow)
	{
		pWindow->RunAsync([=]
		{
			// filterLoadedCallback() should be called on the main thread
			// to ensure atomicity;
			// Must call the callback before sending the message
			filterLoadedCallback(loaded);
			pWindow->SendMessage(UserMessage::WM_USER_MESSAGE,
				loaded ? UserMessage::WPARAM_ABP_FILTER_LOADED : UserMessage::WPARAM_ABP_LOAD_FAILURE, 0);
		});
	}
	else
	{
		// Just a fallback, may never get to here
		filterLoadedCallback(loaded);
	}

	return 0;
}