Skip to content

Commit

Permalink
Fix: Fuzzy matching with filename only, checking for no results. (#48)
Browse files Browse the repository at this point in the history
Signed-off-by: Caroline Russell <[email protected]>
  • Loading branch information
cerrussell authored Apr 12, 2024
1 parent 17d4ab4 commit 073a81f
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 12 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ Regex word boundaries can be used if you only want to be exact about the filenam

This will filter files named server.ts - without the \b, files like ftpserver.ts would also be matched.

>Note: You can search for a file name without including the path if needed and fuzzing ratios will be computed based
> only on the file name.
##### Chaining filter commands

The filter command can act on itself by specifying an additional filter command as an argument.
Expand Down
2 changes: 1 addition & 1 deletion atom_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""
A cli, classes and functions for converting an atom slice to a different format
"""
__version__ = '0.5.3'
__version__ = '0.5.4'
5 changes: 3 additions & 2 deletions atom_tools/cli/commands/query_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@ def handle(self):
self.option('type'),
self.option('input-slice'),
)
if not (result := converter.endpoints_to_openapi('')):
logging.warning('No results produced!')
result = converter.endpoints_to_openapi('')
if not result.get('paths'):
logger.warning('No results produced!')
print('')
else:
line_filter = ()
Expand Down
32 changes: 24 additions & 8 deletions atom_tools/lib/filtering.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Classes and functions for filtering slices"""
import logging
import pathlib
import re
from copy import deepcopy
from dataclasses import dataclass
Expand All @@ -20,7 +21,7 @@ class AttributeFilter:
"""Attribute filter class"""
def __init__(self, key: str, value: str, condition: str, fuzz_pct: int | None) -> None:
self.attribute = key.lower()
self.value, self.line_numbers = create_attribute_filter(value, fuzz_pct)
self.value, self.line_numbers, self.fn_only = create_attribute_filter(key, value, fuzz_pct)
self.condition = condition


Expand Down Expand Up @@ -97,14 +98,15 @@ def _handle_exclude_only(self, exclude: Set[re.Match]) -> Dict:
filtered_slice[key].pop(k)
return filtered_slice

def _process_fuzzy_results(self, f: AttributeFilter, result: List[Tuple[str, int]]) -> None:
def _process_fuzzy_results(
self, f: AttributeFilter, result: List[Tuple[str, int, str]]) -> None:
include = []
exclude = []
for i in result:
if f.condition == '==':
include.extend(self.slc.attrib_dicts.get(f.attribute, {}).get(i[0], []))
include.extend(self.slc.attrib_dicts.get(f.attribute, {}).get(i[2], []))
else:
exclude.extend(self.slc.attrib_dicts.get(f.attribute, {}).get(i[0], []))
exclude.extend(self.slc.attrib_dicts.get(f.attribute, {}).get(i[2], []))
self.results.extend(list(set(include)))
self.negative_results.extend(list(set(exclude)))

Expand All @@ -126,14 +128,20 @@ def _search_values(self, f: AttributeFilter) -> None:
if f.value.search(k):
if f.condition == '==':
include.extend(v)
# self.found_keys.append(k)
else:
exclude.extend(v)
self.results.extend(list(set(include)))
self.negative_results.extend(list(set(exclude)))

def _search_values_fuzzy(self, f: AttributeFilter) -> None:
search_values = self.slc.attrib_dicts.get(f.attribute, {}).keys()
if f.fn_only:
search_values = {
i: f'{pathlib.Path(i).stem}{pathlib.Path(i).suffix}'
for i in search_values
}
else:
search_values = {i: i for i in search_values}
if result := process.extractBests(
f.value,
search_values,
Expand All @@ -144,14 +152,22 @@ def _search_values_fuzzy(self, f: AttributeFilter) -> None:
self._process_fuzzy_results(f, result)


def create_attribute_filter(value: str, fuzz_pct: int | None) -> Tuple:
def create_attribute_filter(key: str, value: str, fuzz_pct: int | None) -> Tuple:
"""Create an attribute filter"""
lns = ()
fn_only = False
if key.lower() == 'filename' and '/' not in value and '\\' not in value:
fn_only = True
if ':' in value and (match := filtering.attribute_and_line.search(value)):
value = match.group('attrib')
lns = get_ln_range(match.group('line_nums'))
new_value = value if fuzz_pct else re.compile(value, re.IGNORECASE)
return new_value, lns
if fuzz_pct:
new_value = value
else:
if '.' in value:
value += '$'
new_value = re.compile(value, re.IGNORECASE) # type: ignore
return new_value, lns, fn_only


def get_ln_range(value: str) -> Tuple[int, int] | Tuple:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "atom-tools"
version = "0.5.3"
version = "0.5.4"
description = "Collection of tools for use with AppThreat/atom."
authors = [
{ name = "Caroline Russell", email = "[email protected]" },
Expand Down

0 comments on commit 073a81f

Please sign in to comment.