Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(analyzers): implement logical operators with analyzers
You can now use multiple analyzers, connected with logical operators (& - and, | - or) so that you have more control over when exactly a paste should match.
- Loading branch information
1 parent
28f707a
commit aed2dbf
Showing
3 changed files
with
149 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# -*- coding: utf-8 -*- | ||
import unittest | ||
from unittest import mock | ||
|
||
from pastepwn.analyzers.basicanalyzer import BasicAnalyzer | ||
|
||
|
||
class TestMergedAnalyzer(unittest.TestCase): | ||
class NewAnalyzer(BasicAnalyzer): | ||
"""Test Analyzer for testing mergedAnalyzer""" | ||
|
||
def __init__(self, return_value): | ||
super().__init__(actions=None) | ||
self.return_value = return_value | ||
|
||
def match(self, paste): | ||
"""Match func""" | ||
return self.return_value | ||
|
||
def setUp(self): | ||
"""Setup test case""" | ||
self.true_analyzer = self.NewAnalyzer(True) | ||
self.false_analyzer = self.NewAnalyzer(False) | ||
self.paste_mock = mock.Mock() | ||
self.paste_mock.body = "This is a mock paste" | ||
|
||
def test_and(self): | ||
"""Check if logical and between analyzers works fine""" | ||
and_analyzer = self.true_analyzer & self.false_analyzer | ||
|
||
# One analyzer returns False, the other True, this should evaluate to False | ||
self.assertFalse(and_analyzer.match(self.paste_mock)) | ||
|
||
and_analyzer2 = self.true_analyzer & self.true_analyzer | ||
# Since both analyzers return true, this should now return True as well | ||
self.assertTrue(and_analyzer2.match(self.paste_mock)) | ||
|
||
def test_or(self): | ||
"""Check if logical or between analyzers works fine""" | ||
# One analyzer returns False, the other True, this should evaluate to True | ||
or_analyzer = self.true_analyzer | self.false_analyzer | ||
self.assertTrue(or_analyzer.match(self.paste_mock)) | ||
|
||
# Since both return true, this should return True as well | ||
or_analyzer2 = self.true_analyzer | self.false_analyzer | ||
self.assertTrue(or_analyzer2.match(self.paste_mock)) | ||
|
||
or_analyzer3 = self.false_analyzer | self.true_analyzer | ||
self.assertTrue(or_analyzer3.match(self.paste_mock)) | ||
|
||
def test_both(self): | ||
"""Check if logical and/or both work fine in combination with each other""" | ||
# One analyzer returns False, the other True, this should evaluate to False | ||
and_analyzer = self.true_analyzer & self.false_analyzer | ||
self.assertFalse(and_analyzer.match(self.paste_mock)) | ||
|
||
# Since both return true, this should return True as well | ||
or_analyzer = self.true_analyzer | self.false_analyzer | ||
self.assertTrue(or_analyzer.match(self.paste_mock)) | ||
|
||
def test_long_chain(self): | ||
"""Check if logical and/or both work fine in long combinations with each other""" | ||
# Long chain of true_analyzers must evaluate to True | ||
and_analyzer = self.true_analyzer & self.true_analyzer & self.true_analyzer & self.true_analyzer & \ | ||
self.true_analyzer & self.true_analyzer & self.true_analyzer & self.true_analyzer | ||
self.assertTrue(and_analyzer.match(self.paste_mock)) | ||
|
||
# A single false_analyzer must make the term evaluate to false | ||
and_analyzer2 = self.true_analyzer & self.true_analyzer & self.true_analyzer & self.false_analyzer & \ | ||
self.true_analyzer & self.true_analyzer & self.true_analyzer & self.true_analyzer | ||
self.assertFalse(and_analyzer2.match(self.paste_mock)) | ||
|
||
# Since one returns true, this should return True as well | ||
or_analyzer = self.false_analyzer | self.false_analyzer | self.false_analyzer | self.false_analyzer | \ | ||
self.false_analyzer | self.true_analyzer | self.true_analyzer | self.true_analyzer | ||
self.assertTrue(or_analyzer.match(self.paste_mock)) | ||
|
||
def test_list_and(self): | ||
"""Check if other return values than booleans are handled correctly with logical and""" | ||
and_analyzer = self.NewAnalyzer(["Test", 123]) & self.NewAnalyzer([]) | ||
res = and_analyzer.match(self.paste_mock) | ||
self.assertIsInstance(res, bool) | ||
self.assertFalse(res) | ||
|
||
def test_list_or(self): | ||
"""Check if other return values than booleans are handled correctly with logical or""" | ||
and_analyzer = self.NewAnalyzer(["Test", 123]) | self.NewAnalyzer([]) | ||
res = and_analyzer.match(self.paste_mock) | ||
self.assertIsInstance(res, bool) | ||
self.assertTrue(res) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |