def testEscaping(self): parser = objectfilter.Parser(r'a is "\n"').Parse() self.assertEqual(parser.args[0], '\n') # Invalid escape sequence. parser = objectfilter.Parser(r'a is "\z"') with self.assertRaises(errors.ParseError): parser.Parse() # Can escape the backslash. parser = objectfilter.Parser(r'a is "\\"').Parse() self.assertEqual(parser.args[0], '\\') # Test hexadecimal escaping. # This fails as it's not really a hex escaped string. parser = objectfilter.Parser(r'a is "\xJZ"') with self.assertRaises(errors.ParseError): parser.Parse() # Instead, this is what one should write. parser = objectfilter.Parser(r'a is "\\xJZ"').Parse() self.assertEqual(parser.args[0], r'\xJZ') # Standard hex-escape. parser = objectfilter.Parser(r'a is "\x41\x41\x41"').Parse() self.assertEqual(parser.args[0], 'AAA') # Hex-escape + a character. parser = objectfilter.Parser(r'a is "\x414"').Parse() self.assertEqual(parser.args[0], r'A4') # How to include r'\x41'. parser = objectfilter.Parser(r'a is "\\x41"').Parse() self.assertEqual(parser.args[0], r'\x41')
def testCompile(self): obj = DummyObject('something', 'Blue') parser = objectfilter.Parser('something == \'Blue\'').Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), True) parser = objectfilter.Parser('something == \'Red\'').Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), False) parser = objectfilter.Parser('something == "Red"').Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), False) obj = DummyObject('size', 4) parser = objectfilter.Parser('size < 3').Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), False) parser = objectfilter.Parser('size == 4').Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), True) query = 'something is \'Blue\' and size not contains 3' parser = objectfilter.Parser(query).Parse() filter_ = parser.Compile(self.filter_imp) self.assertEqual(filter_.Matches(obj), False)
def testParse(self): # Arguments are either int, float or quoted string. objectfilter.Parser('attribute == 1').Parse() objectfilter.Parser('attribute == 0x10').Parse() parser = objectfilter.Parser('attribute == 1a') with self.assertRaises(errors.ParseError): parser.Parse() objectfilter.Parser('attribute == 1.2').Parse() objectfilter.Parser('attribute == \'bla\'').Parse() objectfilter.Parser('attribute == "bla"').Parse() parser = objectfilter.Parser('something == red') self.assertRaises(errors.ParseError, parser.Parse) # Can't start with AND. parser = objectfilter.Parser('and something is \'Blue\'') with self.assertRaises(errors.ParseError): parser.Parse() # Test negative filters. parser = objectfilter.Parser('attribute not == \'dancer\'') with self.assertRaises(errors.ParseError): parser.Parse() parser = objectfilter.Parser('attribute == not \'dancer\'') with self.assertRaises(errors.ParseError): parser.Parse() parser = objectfilter.Parser('attribute not not equals \'dancer\'') with self.assertRaises(errors.ParseError): parser.Parse() parser = objectfilter.Parser('attribute not > 23') with self.assertRaises(errors.ParseError): parser.Parse() # Need to close braces. objectfilter.Parser('(a is 3)').Parse() parser = objectfilter.Parser('(a is 3') self.assertRaises(errors.ParseError, parser.Parse) # Need to open braces to close them. parser = objectfilter.Parser('a is 3)') self.assertRaises(errors.ParseError, parser.Parse) # Context Operator alone is not accepted. parser = objectfilter.Parser('@attributes') with self.assertRaises(errors.ParseError): parser.Parse() # Accepted only with braces. objectfilter.Parser('@attributes( name is \'adrien\')').Parse() # Not without them. parser = objectfilter.Parser('@attributes name is \'adrien\'') with self.assertRaises(errors.ParseError): parser.Parse() # Can nest context operators. query = '@imported_dlls( @imported_function( name is \'OpenFileA\'))' objectfilter.Parser(query).Parse() # Can nest context operators and mix braces without it messing up. query = '@imported_dlls( @imported_function( name is \'OpenFileA\'))' parser = objectfilter.Parser(query).Parse() query = u'\n'.join([ '@imported_dlls', '(', ' @imported_function', ' (', ' name is "OpenFileA" and ordinal == 12', ' )', ')' ]) parser = objectfilter.Parser(query).Parse() # Mix context and binary operators. query = u'\n'.join([ '@imported_dlls', '(', ' @imported_function', ' (', ' name is "OpenFileA"', ' ) AND num_functions == 2', ')' ]) parser = objectfilter.Parser(query).Parse() # Also on the right. query = u'\n'.join([ '@imported_dlls', '(', ' num_functions == 2 AND', ' @imported_function', ' (', ' name is "OpenFileA"', ' )', ')' ])
def testContext(self): self.assertRaises(objectfilter.InvalidNumberOfOperands, objectfilter.Context, arguments=['context'], value_expander=self.value_expander) self.assertRaises( objectfilter.InvalidNumberOfOperands, objectfilter.Context, arguments=[ 'context', objectfilter.Equals(arguments=['path', 'value'], value_expander=self.value_expander), objectfilter.Equals(arguments=['another_path', 'value'], value_expander=self.value_expander) ], value_expander=self.value_expander) # One imported_dll imports 2 functions AND one imported_dll imports # function RegQueryValueEx. arguments = [ objectfilter.Equals( arguments=['imported_dlls.num_imported_functions', 1], value_expander=self.value_expander), objectfilter.Contains(arguments=[ 'imported_dlls.imported_functions', 'RegQueryValueEx' ], value_expander=self.value_expander) ] condition = objectfilter.AndFilter(arguments=arguments) # Without context, it matches because both filters match separately. self.assertEqual(True, condition.Matches(self.file)) arguments = [ objectfilter.Equals(arguments=['num_imported_functions', 2], value_expander=self.value_expander), objectfilter.Contains( arguments=['imported_functions', 'RegQueryValueEx'], value_expander=self.value_expander) ] condition = objectfilter.AndFilter(arguments=arguments) # The same DLL imports 2 functions AND one of these is RegQueryValueEx. context = objectfilter.Context(arguments=['imported_dlls', condition], value_expander=self.value_expander) # With context, it doesn't match because both don't match in the same dll. self.assertEqual(False, context.Matches(self.file)) # One imported_dll imports only 1 function AND one imported_dll imports # function RegQueryValueEx. condition = objectfilter.AndFilter(arguments=[ objectfilter.Equals(arguments=['num_imported_functions', 1], value_expander=self.value_expander), objectfilter.Contains( arguments=['imported_functions', 'RegQueryValueEx'], value_expander=self.value_expander) ]) # The same DLL imports 1 function AND it's RegQueryValueEx. context = objectfilter.Context(['imported_dlls', condition], value_expander=self.value_expander) self.assertEqual(True, context.Matches(self.file)) # Now test the context with a straight query. query = u'\n'.join([ '@imported_dlls', '(', ' imported_functions contains "RegQueryValueEx"', ' AND num_imported_functions == 1', ')' ]) filter_ = objectfilter.Parser(query).Parse() filter_ = filter_.Compile(self.filter_imp) self.assertEqual(True, filter_.Matches(self.file))