Skip to content

Commit

Permalink
Merge pull request #306 from frack113:casesensitive
Browse files Browse the repository at this point in the history
Add CaseTransformation
  • Loading branch information
thomaspatzke authored Nov 17, 2024
2 parents 33f0654 + ba4bd8f commit 626fd2a
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
2 changes: 2 additions & 0 deletions sigma/processing/transformations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
RegexTransformation,
ReplaceStringTransformation,
SetValueTransformation,
CaseTransformation,
)

transformations: Dict[str, Transformation] = {
Expand Down Expand Up @@ -62,4 +63,5 @@
"detection_item_failure": DetectionItemFailureTransformation,
"set_custom_attribute": SetCustomAttributeTransformation,
"nest": NestedProcessingTransformation,
"case": CaseTransformation,
}
21 changes: 21 additions & 0 deletions sigma/processing/transformations/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,3 +369,24 @@ def apply_value(self, field: str, val: SigmaType) -> Optional[Union[SigmaString,
return SigmaNumber(str(val))
except SigmaValueError:
raise SigmaValueError(f"Value '{val}' can't be converted to number for {str(self)}")


@dataclass
class CaseTransformation(StringValueTransformation):
"""
Transform a string value to a lower or upper case.
"""

method: Literal["lower", "upper"] = "lower"

def __post_init__(self):
if self.method not in self.__annotations__["method"].__args__:
raise SigmaConfigurationError(f"Invalid method '{self.method}' for CaseTransformation.")
return super().__post_init__()

def apply_string_value(self, field: str, val: SigmaString) -> Optional[SigmaString]:

if self.method == "lower":
return val.lower()
else:
return val.upper()
6 changes: 6 additions & 0 deletions sigma/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,12 @@ def to_regex(self, custom_escaped: str = "") -> "SigmaRegularExpression":
)
)

def upper(self) -> "SigmaString":
return self.map_parts(str.upper, lambda x: isinstance(x, str))

def lower(self) -> "SigmaString":
return self.map_parts(str.lower, lambda x: isinstance(x, str))


class SigmaCasedString(SigmaString):
"""Case-sensitive string matching."""
Expand Down
35 changes: 35 additions & 0 deletions tests/test_processing_transformations.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
AddFieldnamePrefixTransformation,
AddFieldnameSuffixTransformation,
AddFieldTransformation,
CaseTransformation,
ChangeLogsourceTransformation,
ConvertTypeTransformation,
DetectionItemFailureTransformation,
Expand Down Expand Up @@ -2025,3 +2026,37 @@ def test_hashes_transformation_pipe_separator(hashes_transformation):
assert result.detection_items[0].value == [
SigmaString("5F1CBC3D99558307BC1250D084FA968521482025")
]


def test_case_transformation_lower(dummy_pipeline):
detection_item = SigmaDetectionItem("field", [], [SigmaString("AbC")])
transformation = CaseTransformation(method="lower")
transformation.apply_detection_item(detection_item)
assert detection_item.value[0] == SigmaString("abc")


def test_case_transformation_upper(dummy_pipeline):
detection_item = SigmaDetectionItem("field", [], [SigmaString("AbC")])
transformation = CaseTransformation(method="upper")
transformation.apply_detection_item(detection_item)
assert detection_item.value[0] == SigmaString("ABC")


def test_case_transformation_special(dummy_pipeline):
detection_item = SigmaDetectionItem("field", [], [SigmaString("AbC*zer?.123\\")])
transformation = CaseTransformation(method="upper")
transformation.apply_detection_item(detection_item)
assert detection_item.value[0].s == (
"ABC",
SpecialChars.WILDCARD_MULTI,
"ZER",
SpecialChars.WILDCARD_SINGLE,
".123\\",
)


def test_case_transformation_error():
with pytest.raises(
SigmaConfigurationError, match="Invalid method 'SnakeCase' for CaseTransformation."
):
transformation = CaseTransformation(method="SnakeCase")

0 comments on commit 626fd2a

Please sign in to comment.