loolwsd/Util.hpp | 59 +++++++++++++++++++++++++++++++++++++ loolwsd/test/Makefile.am | 2 - loolwsd/test/WhiteBoxTests.cpp | 65 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 1 deletion(-)
New commits: commit 7d65e30595adef30ef8d0381cc9bca67cd41d8dd Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Mon Apr 18 18:52:10 2016 -0400 loolwsd: regex matching class against whitelist/blacklist With unittests. Change-Id: Ibb14c493cc6de61b6497ab84e34e105481afe464 Reviewed-on: https://gerrit.libreoffice.org/24231 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/loolwsd/Util.hpp b/loolwsd/Util.hpp index 223d0fb..1635c5d 100644 --- a/loolwsd/Util.hpp +++ b/loolwsd/Util.hpp @@ -14,11 +14,13 @@ #include <sstream> #include <functional> #include <memory> +#include <set> #include <Poco/File.h> #include <Poco/Path.h> #include <Poco/Process.h> #include <Poco/Net/WebSocket.h> +#include <Poco/RegularExpression.h> #define LOK_USE_UNSTABLE_API #include <LibreOfficeKit/LibreOfficeKitEnums.h> @@ -117,6 +119,63 @@ namespace Util /// Display version information void displayVersionInfo(const char *app); + + /// Given one or more patterns to allow, and one or more to deny, + /// the match member will return true if, and only if, the subject + /// matches the allowed list, but not the deny. + /// By default, everything is denied. + class RegexListMatcher + { + public: + void allow(const std::string& pattern) { _allowed.insert(pattern); } + void deny(const std::string& pattern) + { + _allowed.erase(pattern); + _denied.insert(pattern); + } + + bool match(const std::string& subject) const + { + return (match(_allowed, subject) && !match(_denied, subject)); + } + + private: + bool match(const std::set<std::string>& set, const std::string& subject) const + { + if (set.find(subject) != set.end()) + { + return true; + } + + // Not a perfect match, try regex. + for (const auto& value : set) + { + try + { + // Not performance critical to warrant caching. + Poco::RegularExpression re(value, Poco::RegularExpression::RE_CASELESS); + Poco::RegularExpression::Match match; + + // Must be a full match. + if (re.match(subject, match) && match.offset == 0 && match.length == subject.size()) + { + return true; + } + } + catch (const std::exception& exc) + { + // Nothing to do; skip. + } + } + + return false; + } + + private: + std::set<std::string> _allowed; + std::set<std::string> _denied; + }; + }; #endif diff --git a/loolwsd/test/Makefile.am b/loolwsd/test/Makefile.am index 721ec0c..0a40ef3 100644 --- a/loolwsd/test/Makefile.am +++ b/loolwsd/test/Makefile.am @@ -13,7 +13,7 @@ AM_LDFLAGS = -module $(MAGIC_TO_FORCE_SHLIB_CREATION) AM_CPPFLAGS = -pthread -I$(top_srcdir) test_CPPFLAGS = -DTDOC=\"$(top_srcdir)/test/data\" -test_SOURCES = httpposttest.cpp httpwstest.cpp test.cpp ../LOOLProtocol.cpp +test_SOURCES = WhiteBoxTests.cpp httpposttest.cpp httpwstest.cpp test.cpp ../LOOLProtocol.cpp test_LDADD = $(CPPUNIT_LIBS) # unit test modules: diff --git a/loolwsd/test/WhiteBoxTests.cpp b/loolwsd/test/WhiteBoxTests.cpp new file mode 100644 index 0000000..79104f1 --- /dev/null +++ b/loolwsd/test/WhiteBoxTests.cpp @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "config.h" + +#include <cppunit/extensions/HelperMacros.h> + +#include <Common.hpp> +#include <Util.hpp> + +/// WhiteBox unit-tests. +class WhiteBoxTests : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE(WhiteBoxTests); + + CPPUNIT_TEST(testRegexListMatcher); + + CPPUNIT_TEST_SUITE_END(); + + void testRegexListMatcher(); +}; + +void WhiteBoxTests::testRegexListMatcher() +{ + Util::RegexListMatcher matcher; + + matcher.allow("localhost"); + CPPUNIT_ASSERT(matcher.match("localhost")); + CPPUNIT_ASSERT(!matcher.match("")); + CPPUNIT_ASSERT(!matcher.match("localhost2")); + CPPUNIT_ASSERT(!matcher.match("xlocalhost")); + CPPUNIT_ASSERT(!matcher.match("192.168.1.1")); + + matcher.deny("localhost"); + CPPUNIT_ASSERT(!matcher.match("localhost")); + + matcher.allow("www[0-9].*"); + CPPUNIT_ASSERT(matcher.match("www1example")); + + matcher.allow("192\\.168\\..*\\..*"); + CPPUNIT_ASSERT(matcher.match("192.168.1.1")); + CPPUNIT_ASSERT(matcher.match("192.168.159.1")); + CPPUNIT_ASSERT(matcher.match("192.168.1.134")); + CPPUNIT_ASSERT(!matcher.match("192.169.1.1")); + CPPUNIT_ASSERT(matcher.match("192.168..")); + + matcher.deny("192\\.168\\.1\\..*"); + CPPUNIT_ASSERT(!matcher.match("192.168.1.1")); + + matcher.allow("staging\\.collaboracloudsuite\\.com.*"); + matcher.deny(".*collaboracloudsuite.*"); + CPPUNIT_ASSERT(!matcher.match("staging.collaboracloudsuite")); + CPPUNIT_ASSERT(!matcher.match("web.collaboracloudsuite")); + CPPUNIT_ASSERT(!matcher.match("staging.collaboracloudsuite.com")); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(WhiteBoxTests); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits