prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  endswith Modifier broken
  In 2fafff3, a bug was introduced breaking the endswith modifier.
  The fix correctly changed the behaviour of the contains modifier but also wrongly applied the fix to endswith instead of startswith.
  
  </issue>
  <code>
  [start of tools/sigma/parser/modifiers/transform.py]
  1 # Sigma value modifiers
  2 # Copyright 2019 Thomas Patzke, Florian Roth
  3 
  4 # This program is free software: you can redistribute it and/or modify
  5 # it under the terms of the GNU Lesser General Public License as published by
  6 # the Free Software Foundation, either version 3 of the License, or
  7 # (at your option) any later version.
  8 
  9 # This program is distributed in the hope that it will be useful,
  10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 # GNU Lesser General Public License for more details.
  13 
  14 # You should have received a copy of the GNU Lesser General Public License
  15 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16 
  17 from .base import SigmaTransformModifier
  18 from .mixins import ListOrStringModifierMixin
  19 from sigma.parser.condition import ConditionAND
  20 from base64 import b64encode
  21 
  22 class SigmaContainsModifier(ListOrStringModifierMixin, SigmaTransformModifier):
  23     """Add *-wildcard before and after all string(s)"""
  24     identifier = "contains"
  25     active = True
  26 
  27     def apply_str(self, val : str):
  28         if not val.startswith("*"):
  29             val = "*" + val
  30         if not val.endswith("*"):
  31             if val.endswith("\\"):
  32                 val += "\\*"
  33             else:
  34                 val += "*"
  35         return val
  36 
  37 class SigmaStartswithModifier(ListOrStringModifierMixin, SigmaTransformModifier):
  38     """Add *-wildcard before and after all string(s)"""
  39     identifier = "startswith"
  40     active = True
  41 
  42     def apply_str(self, val : str):
  43         if not val.endswith("*"):
  44             val += "*"
  45         return val
  46 
  47 class SigmaEndswithModifier(ListOrStringModifierMixin, SigmaTransformModifier):
  48     """Add *-wildcard before and after all string(s)"""
  49     identifier = "endswith"
  50     active = True
  51 
  52     def apply_str(self, val : str):
  53         if not val.startswith("*"):
  54             if val.endswith("\\"):
  55                 val += "\\*"
  56             else:
  57                 val += "*"
  58         return val
  59 
  60 class SigmaAllValuesModifier(SigmaTransformModifier):
  61     """Override default OR-linking behavior for list with AND-linking of all list values"""
  62     identifier = "all"
  63     active = True
  64     valid_input_types = (list, tuple, )
  65 
  66     def apply(self):
  67         vals = super().apply()
  68         cond = ConditionAND()
  69         for val in self.value:
  70             cond.add(val)
  71         return cond
  72 
  73 class SigmaBase64Modifier(ListOrStringModifierMixin, SigmaTransformModifier):
  74     """Encode strings with Base64"""
  75     identifier = "base64"
  76     active = True
  77     valid_input_types = ListOrStringModifierMixin.valid_input_types + (bytes,)
  78 
  79     def apply_str(self, val):
  80         if type(val) == str:
  81             val = val.encode()
  82         return b64encode(val).decode()
  83 
  84 class SigmaBase64OffsetModifier(ListOrStringModifierMixin, SigmaTransformModifier):
  85     """Encode string(s) with Base64 in all three possible shifted offsets"""
  86     identifier = "base64offset"
  87     active = True
  88     valid_input_types = ListOrStringModifierMixin.valid_input_types + (bytes,)
  89 
  90     start_offsets = (0, 2, 3)
  91     end_offsets = (None, -3, -2)
  92 
  93     def apply_str(self, val):
  94         if type(val) == str:
  95             val = val.encode()
  96         return [
  97                 b64encode(
  98                     i * b' ' + val
  99                     )[
  100                         self.start_offsets[i]:
  101                         self.end_offsets[(len(val) + i) % 3]
  102                         ].decode()
  103                 for i in range(3)
  104                 ]
  105 
  106 class SigmaEncodingBaseModifier(ListOrStringModifierMixin, SigmaTransformModifier):
  107     """
  108     Encode string to a byte sequence with the encoding given in the encoding property. This is
  109     a base class for all encoding modifiers.
  110     """
  111     identifier = "encoding-base"
  112     active = False
  113     encoding = "ascii"
  114 
  115     def apply_str(self, val):
  116         return val.encode(self.encoding)
  117 
  118 class SigmaEncodeUTF16Modifier(SigmaEncodingBaseModifier):
  119     """Encode string to UTF-16 byte sequence"""
  120     identifier = "utf16"
  121     active = True
  122     encoding = "utf-16"
  123 
  124 class SigmaEncodeUTF16LEModifier(SigmaEncodingBaseModifier):
  125     """Encode string to UTF-16 little endian byte sequence"""
  126     identifier = "utf16le"
  127     active = True
  128     encoding = "utf-16le"
  129 
  130 class SigmaEncodeWideModifier(SigmaEncodeUTF16LEModifier):
  131     """Modifier 'wide' is an alias for the utf16le modifier."""
  132     identifier = "wide"
  133 
  134 class SigmaEncodeUTF16BEModifier(SigmaEncodingBaseModifier):
  135     """Encode string to UTF-16 big endian byte sequence"""
  136     identifier = "utf16be"
  137     active = True
  138     encoding = "utf-16be"
  139
  [end of tools/sigma/parser/modifiers/transform.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/tools/sigma/parser/modifiers/transform.py b/tools/sigma/parser/modifiers/transform.py
  --- a/tools/sigma/parser/modifiers/transform.py
  +++ b/tools/sigma/parser/modifiers/transform.py
  @@ -41,7 +41,10 @@
   
       def apply_str(self, val : str):
           if not val.endswith("*"):
  -            val += "*"
  +            if val.endswith("\\"):
  +                val += "\\*"
  +            else:
  +                val += "*"
           return val
   
   class SigmaEndswithModifier(ListOrStringModifierMixin, SigmaTransformModifier):
  @@ -51,10 +54,7 @@
   
       def apply_str(self, val : str):
           if not val.startswith("*"):
  -            if val.endswith("\\"):
  -                val += "\\*"
  -            else:
  -                val += "*"
  +           val = '*' + val
           return val
   
   class SigmaAllValuesModifier(SigmaTransformModifier):
  
verification_info: {"golden_diff": "diff --git a/tools/sigma/parser/modifiers/transform.py b/tools/sigma/parser/modifiers/transform.py\n--- a/tools/sigma/parser/modifiers/transform.py\n+++ b/tools/sigma/parser/modifiers/transform.py\n@@ -41,7 +41,10 @@\n \n     def apply_str(self, val : str):\n         if not val.endswith(\"*\"):\n-            val += \"*\"\n+            if val.endswith(\"\\\\\"):\n+                val += \"\\\\*\"\n+            else:\n+                val += \"*\"\n         return val\n \n class SigmaEndswithModifier(ListOrStringModifierMixin, SigmaTransformModifier):\n@@ -51,10 +54,7 @@\n \n     def apply_str(self, val : str):\n         if not val.startswith(\"*\"):\n-            if val.endswith(\"\\\\\"):\n-                val += \"\\\\*\"\n-            else:\n-                val += \"*\"\n+           val = '*' + val\n         return val\n \n class SigmaAllValuesModifier(SigmaTransformModifier):\n", "issue": "endswith Modifier broken\nIn 2fafff3, a bug was introduced breaking the endswith modifier.\r\nThe fix correctly changed the behaviour of the contains modifier but also wrongly applied the fix to endswith instead of startswith.\n", "before_files": [{"content": "# Sigma value modifiers\n# Copyright 2019 Thomas Patzke, Florian Roth\n\n# This program is free software: you can redistribute it and/or modify\n# it under the terms of the GNU Lesser General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU Lesser General Public License for more details.\n\n# You should have received a copy of the GNU Lesser General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nfrom .base import SigmaTransformModifier\nfrom .mixins import ListOrStringModifierMixin\nfrom sigma.parser.condition import ConditionAND\nfrom base64 import b64encode\n\nclass SigmaContainsModifier(ListOrStringModifierMixin, SigmaTransformModifier):\n    \"\"\"Add *-wildcard before and after all string(s)\"\"\"\n    identifier = \"contains\"\n    active = True\n\n    def apply_str(self, val : str):\n        if not val.startswith(\"*\"):\n            val = \"*\" + val\n        if not val.endswith(\"*\"):\n            if val.endswith(\"\\\\\"):\n                val += \"\\\\*\"\n            else:\n                val += \"*\"\n        return val\n\nclass SigmaStartswithModifier(ListOrStringModifierMixin, SigmaTransformModifier):\n    \"\"\"Add *-wildcard before and after all string(s)\"\"\"\n    identifier = \"startswith\"\n    active = True\n\n    def apply_str(self, val : str):\n        if not val.endswith(\"*\"):\n            val += \"*\"\n        return val\n\nclass SigmaEndswithModifier(ListOrStringModifierMixin, SigmaTransformModifier):\n    \"\"\"Add *-wildcard before and after all string(s)\"\"\"\n    identifier = \"endswith\"\n    active = True\n\n    def apply_str(self, val : str):\n        if not val.startswith(\"*\"):\n            if val.endswith(\"\\\\\"):\n                val += \"\\\\*\"\n            else:\n                val += \"*\"\n        return val\n\nclass SigmaAllValuesModifier(SigmaTransformModifier):\n    \"\"\"Override default OR-linking behavior for list with AND-linking of all list values\"\"\"\n    identifier = \"all\"\n    active = True\n    valid_input_types = (list, tuple, )\n\n    def apply(self):\n        vals = super().apply()\n        cond = ConditionAND()\n        for val in self.value:\n            cond.add(val)\n        return cond\n\nclass SigmaBase64Modifier(ListOrStringModifierMixin, SigmaTransformModifier):\n    \"\"\"Encode strings with Base64\"\"\"\n    identifier = \"base64\"\n    active = True\n    valid_input_types = ListOrStringModifierMixin.valid_input_types + (bytes,)\n\n    def apply_str(self, val):\n        if type(val) == str:\n            val = val.encode()\n        return b64encode(val).decode()\n\nclass SigmaBase64OffsetModifier(ListOrStringModifierMixin, SigmaTransformModifier):\n    \"\"\"Encode string(s) with Base64 in all three possible shifted offsets\"\"\"\n    identifier = \"base64offset\"\n    active = True\n    valid_input_types = ListOrStringModifierMixin.valid_input_types + (bytes,)\n\n    start_offsets = (0, 2, 3)\n    end_offsets = (None, -3, -2)\n\n    def apply_str(self, val):\n        if type(val) == str:\n            val = val.encode()\n        return [\n                b64encode(\n                    i * b' ' + val\n                    )[\n                        self.start_offsets[i]:\n                        self.end_offsets[(len(val) + i) % 3]\n                        ].decode()\n                for i in range(3)\n                ]\n\nclass SigmaEncodingBaseModifier(ListOrStringModifierMixin, SigmaTransformModifier):\n    \"\"\"\n    Encode string to a byte sequence with the encoding given in the encoding property. This is\n    a base class for all encoding modifiers.\n    \"\"\"\n    identifier = \"encoding-base\"\n    active = False\n    encoding = \"ascii\"\n\n    def apply_str(self, val):\n        return val.encode(self.encoding)\n\nclass SigmaEncodeUTF16Modifier(SigmaEncodingBaseModifier):\n    \"\"\"Encode string to UTF-16 byte sequence\"\"\"\n    identifier = \"utf16\"\n    active = True\n    encoding = \"utf-16\"\n\nclass SigmaEncodeUTF16LEModifier(SigmaEncodingBaseModifier):\n    \"\"\"Encode string to UTF-16 little endian byte sequence\"\"\"\n    identifier = \"utf16le\"\n    active = True\n    encoding = \"utf-16le\"\n\nclass SigmaEncodeWideModifier(SigmaEncodeUTF16LEModifier):\n    \"\"\"Modifier 'wide' is an alias for the utf16le modifier.\"\"\"\n    identifier = \"wide\"\n\nclass SigmaEncodeUTF16BEModifier(SigmaEncodingBaseModifier):\n    \"\"\"Encode string to UTF-16 big endian byte sequence\"\"\"\n    identifier = \"utf16be\"\n    active = True\n    encoding = \"utf-16be\"\n", "path": "tools/sigma/parser/modifiers/transform.py"}]}