Skip to content

Added Independent Finding Execution Behavior #1030

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Apr 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d7d0c9a
Codemods will now execute once for each finding independently
andrecsilva Mar 12, 2025
874743b
Adjusted tests to account for individual changes diff
andrecsilva Mar 12, 2025
66fd2f3
Fixed a few more unit tests
andrecsilva Mar 13, 2025
9b3e827
Fixed a few more tests
andrecsilva Mar 13, 2025
abe872a
Fixed more unit tests
andrecsilva Mar 14, 2025
141cde2
Fixed more unit tests
andrecsilva Mar 14, 2025
1aa72fd
Added hardening script
andrecsilva Mar 24, 2025
a8e59a2
Added integration tests for new behavior
andrecsilva Mar 20, 2025
64aef85
Added file rewritten check
andrecsilva Mar 21, 2025
222e649
Fixed some integration tests
andrecsilva Mar 21, 2025
3df2907
More integration tests converted
andrecsilva Mar 24, 2025
22a55bb
Fixed a few more tests
andrecsilva Mar 24, 2025
e0d2b81
Remove leftover debugging code
andrecsilva Mar 24, 2025
f5bdf33
Fixed broken dependency and some docstrings
andrecsilva Mar 24, 2025
139926d
Fixed pygoat workflow file
andrecsilva Mar 24, 2025
22dd701
Fixed some intermittent tests
andrecsilva Mar 24, 2025
233974a
Some refactoring
andrecsilva Mar 25, 2025
301379b
More refactoring
andrecsilva Mar 25, 2025
ae4b6b5
Small refactoring
andrecsilva Mar 25, 2025
1bf27c6
Reverted default behavior to hardening
andrecsilva Mar 28, 2025
2ab7c0b
Fixed pygoat test
andrecsilva Mar 28, 2025
04f5a99
Refactored hardening and remediation behavior
andrecsilva Mar 28, 2025
e994695
Fixed skipping logic
andrecsilva Mar 28, 2025
0582137
Fixed asserts in integration tests with sonar issues
andrecsilva Apr 3, 2025
18cd5e7
Removed debugging code
andrecsilva Apr 3, 2025
63e302a
Downgraded pydantic version and bumped sarif-pydantic
andrecsilva Apr 9, 2025
bb95515
Added method to create ResultSets from the same type
andrecsilva Apr 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 7 additions & 28 deletions integration_tests/sonar/test_sonar_fix_missing_self_or_cls.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,17 @@
from codemodder.codemods.test import SonarIntegrationTest
from codemodder.codemods.test.integration_utils import SonarRemediationIntegrationTest
from core_codemods.fix_missing_self_or_cls import FixMissingSelfOrClsTransformer
from core_codemods.sonar.sonar_fix_missing_self_or_cls import SonarFixMissingSelfOrCls


class TestSonarFixMissingSelfOrCls(SonarIntegrationTest):
class TestSonarFixMissingSelfOrCls(SonarRemediationIntegrationTest):
codemod = SonarFixMissingSelfOrCls
code_path = "tests/samples/fix_missing_self_or_cls.py"
replacement_lines = [
(
2,
""" def instance_method(self):\n""",
),
(
6,
""" def class_method(cls):\n""",
),

expected_diff_per_change = [
'--- \n+++ \n@@ -1,5 +1,5 @@\n class MyClass:\n- def instance_method():\n+ def instance_method(self):\n print("instance_method")\n \n @classmethod\n',
'--- \n+++ \n@@ -3,5 +3,5 @@\n print("instance_method")\n \n @classmethod\n- def class_method():\n+ def class_method(cls):\n print("class_method")\n',
]
# fmt: off
expected_diff = (
"""--- \n"""
"""+++ \n"""
"""@@ -1,7 +1,7 @@\n"""
""" class MyClass:\n"""
"""- def instance_method():\n"""
"""+ def instance_method(self):\n"""
""" print("instance_method")\n"""
""" \n"""
""" @classmethod\n"""
"""- def class_method():\n"""
"""+ def class_method(cls):\n"""
""" print("class_method")\n"""
)
# fmt: on

expected_line_change = "2"
expected_lines_changed = [2, 6]
change_description = FixMissingSelfOrClsTransformer.change_description
num_changes = 2
14 changes: 7 additions & 7 deletions integration_tests/sonar/test_sonar_jinja2_autoescape.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
from codemodder.codemods.test import SonarIntegrationTest
from codemodder.codemods.test.integration_utils import SonarRemediationIntegrationTest
from core_codemods.enable_jinja2_autoescape import EnableJinja2AutoescapeTransformer
from core_codemods.sonar.sonar_enable_jinja2_autoescape import (
SonarEnableJinja2Autoescape,
)


class TestSonarEnableJinja2Autoescape(SonarIntegrationTest):
class TestSonarEnableJinja2Autoescape(SonarRemediationIntegrationTest):
codemod = SonarEnableJinja2Autoescape
code_path = "tests/samples/jinja2_autoescape.py"
replacement_lines = [
(3, "env = Environment(autoescape=True)\n"),
(4, "env = Environment(autoescape=True)\n"),
expected_diff_per_change = [
"--- \n+++ \n@@ -1,4 +1,4 @@\n from jinja2 import Environment\n \n-env = Environment()\n+env = Environment(autoescape=True)\n env = Environment(autoescape=False)\n",
"--- \n+++ \n@@ -1,4 +1,4 @@\n from jinja2 import Environment\n \n env = Environment()\n-env = Environment(autoescape=False)\n+env = Environment(autoescape=True)\n",
]
expected_diff = "--- \n+++ \n@@ -1,4 +1,4 @@\n from jinja2 import Environment\n \n-env = Environment()\n-env = Environment(autoescape=False)\n+env = Environment(autoescape=True)\n+env = Environment(autoescape=True)\n"
expected_line_change = "3"

expected_lines_changed = [3, 4]
num_changes = 2
change_description = EnableJinja2AutoescapeTransformer.change_description
20 changes: 7 additions & 13 deletions integration_tests/sonar/test_sonar_jwt_decode_verify.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
from codemodder.codemods.test import SonarIntegrationTest
from codemodder.codemods.test.integration_utils import SonarRemediationIntegrationTest
from core_codemods.sonar.sonar_jwt_decode_verify import (
JwtDecodeVerifySASTTransformer,
SonarJwtDecodeVerify,
)


class TestJwtDecodeVerify(SonarIntegrationTest):
class TestJwtDecodeVerify(SonarRemediationIntegrationTest):
codemod = SonarJwtDecodeVerify
code_path = "tests/samples/jwt_decode_verify.py"
replacement_lines = [
(
11,
"""decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], verify=True)\n""",
),
(
12,
"""decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], options={"verify_signature": True})\n""",
),

expected_diff_per_change = [
'--- \n+++ \n@@ -8,7 +8,7 @@\n \n encoded_jwt = jwt.encode(payload, SECRET_KEY, algorithm="HS256")\n \n-decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], verify=False)\n+decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], verify=True)\n decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], options={"verify_signature": False})\n \n var = "something"\n',
'--- \n+++ \n@@ -9,6 +9,6 @@\n encoded_jwt = jwt.encode(payload, SECRET_KEY, algorithm="HS256")\n \n decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], verify=False)\n-decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], options={"verify_signature": False})\n+decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], options={"verify_signature": True})\n \n var = "something"\n',
]

expected_diff = '--- \n+++ \n@@ -8,7 +8,7 @@\n \n encoded_jwt = jwt.encode(payload, SECRET_KEY, algorithm="HS256")\n \n-decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], verify=False)\n-decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], options={"verify_signature": False})\n+decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], verify=True)\n+decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], options={"verify_signature": True})\n \n var = "something"\n'
expected_line_change = "11"
expected_lines_changed = [11, 12]
num_changes = 2
change_description = JwtDecodeVerifySASTTransformer.change_description
17 changes: 8 additions & 9 deletions integration_tests/sonar/test_sonar_secure_cookie.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
from codemodder.codemods.test import SonarIntegrationTest
from codemodder.codemods.test.integration_utils import SonarRemediationIntegrationTest
from core_codemods.sonar.sonar_secure_cookie import (
SonarSecureCookie,
SonarSecureCookieTransformer,
)


class TestSonarSecureCookie(SonarIntegrationTest):
class TestSonarSecureCookie(SonarRemediationIntegrationTest):
codemod = SonarSecureCookie
code_path = "tests/samples/secure_cookie.py"
replacement_lines = [
(
8,
""" resp.set_cookie('custom_cookie', 'value', secure=True, httponly=True, samesite='Lax')\n""",
),
expected_diff_per_change = [
"--- \n+++ \n@@ -5,5 +5,5 @@\n @app.route('/')\n def index():\n resp = make_response('Custom Cookie Set')\n- resp.set_cookie('custom_cookie', 'value')\n+ resp.set_cookie('custom_cookie', 'value', secure=True, httponly=True, samesite='Lax')\n return resp\n",
"--- \n+++ \n@@ -5,5 +5,5 @@\n @app.route('/')\n def index():\n resp = make_response('Custom Cookie Set')\n- resp.set_cookie('custom_cookie', 'value')\n+ resp.set_cookie('custom_cookie', 'value', secure=True, httponly=True, samesite='Lax')\n return resp\n",
]
expected_diff = "--- \n+++ \n@@ -5,5 +5,5 @@\n @app.route('/')\n def index():\n resp = make_response('Custom Cookie Set')\n- resp.set_cookie('custom_cookie', 'value')\n+ resp.set_cookie('custom_cookie', 'value', secure=True, httponly=True, samesite='Lax')\n return resp\n"
expected_line_change = "8"

expected_lines_changed = [8, 8]
num_changes = 2
change_description = SonarSecureCookieTransformer.change_description
27 changes: 7 additions & 20 deletions integration_tests/sonar/test_sonar_secure_random.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
from codemodder.codemods.test import SonarIntegrationTest
from codemodder.codemods.test.integration_utils import SonarRemediationIntegrationTest
from core_codemods.secure_random import SecureRandomTransformer
from core_codemods.sonar.sonar_secure_random import SonarSecureRandom


class TestSonarDjangoJsonResponseType(SonarIntegrationTest):
class TestSonarSecureRandom(SonarRemediationIntegrationTest):
codemod = SonarSecureRandom
code_path = "tests/samples/secure_random.py"
replacement_lines = [
(1, """import secrets\n"""),
(3, """secrets.SystemRandom().random()\n"""),
(4, """secrets.SystemRandom().getrandbits(1)\n"""),
expected_diff_per_change = [
"--- \n+++ \n@@ -1,4 +1,5 @@\n import random\n+import secrets\n \n-random.random()\n+secrets.SystemRandom().random()\n random.getrandbits(1)\n",
"--- \n+++ \n@@ -1,4 +1,5 @@\n import random\n+import secrets\n \n random.random()\n-random.getrandbits(1)\n+secrets.SystemRandom().getrandbits(1)\n",
]
# fmt: off
expected_diff = (
"""--- \n"""
"""+++ \n"""
"""@@ -1,4 +1,4 @@\n"""
"""-import random\n"""
"""+import secrets\n"""
""" \n"""
"""-random.random()\n"""
"""-random.getrandbits(1)\n"""
"""+secrets.SystemRandom().random()\n"""
"""+secrets.SystemRandom().getrandbits(1)\n""")
# fmt: on
expected_line_change = "3"

expected_lines_changed = [3, 4]
change_description = SecureRandomTransformer.change_description
num_changes = 2
26 changes: 6 additions & 20 deletions integration_tests/test_add_requests_timeout.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from requests.exceptions import ConnectionError

from codemodder.codemods.test import BaseIntegrationTest
from codemodder.codemods.test.integration_utils import BaseRemediationIntegrationTest
from core_codemods.add_requests_timeouts import (
AddRequestsTimeouts,
TransformAddRequestsTimeouts,
)


class TestAddRequestsTimeouts(BaseIntegrationTest):
class TestAddRequestsTimeouts(BaseRemediationIntegrationTest):
codemod = AddRequestsTimeouts
original_code = """
import requests
Expand All @@ -18,27 +18,13 @@ class TestAddRequestsTimeouts(BaseIntegrationTest):
requests.post("https://example.com", verify=False)
"""

replacement_lines = [
(3, 'requests.get("https://example.com", timeout=60)\n'),
(6, 'requests.post("https://example.com", verify=False, timeout=60)\n'),
expected_diff_per_change = [
'--- \n+++ \n@@ -1,6 +1,6 @@\n import requests\n \n-requests.get("https://example.com")\n+requests.get("https://example.com", timeout=60)\n requests.get("https://example.com", timeout=1)\n requests.get("https://example.com", timeout=(1, 10), verify=False)\n requests.post("https://example.com", verify=False)',
'--- \n+++ \n@@ -3,4 +3,4 @@\n requests.get("https://example.com")\n requests.get("https://example.com", timeout=1)\n requests.get("https://example.com", timeout=(1, 10), verify=False)\n-requests.post("https://example.com", verify=False)\n+requests.post("https://example.com", verify=False, timeout=60)',
]

expected_diff = """\
---
+++
@@ -1,6 +1,6 @@
import requests

-requests.get("https://example.com")
+requests.get("https://example.com", timeout=60)
requests.get("https://example.com", timeout=1)
requests.get("https://example.com", timeout=(1, 10), verify=False)
-requests.post("https://example.com", verify=False)
+requests.post("https://example.com", verify=False, timeout=60)
"""

num_changes = 2
expected_line_change = "3"
expected_lines_changed = [3, 6]
change_description = TransformAddRequestsTimeouts.change_description
# expected because requests are made
allowed_exceptions = (ConnectionError,)
14 changes: 7 additions & 7 deletions integration_tests/test_harden_ruamel.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
from codemodder.codemods.test import BaseIntegrationTest
from codemodder.codemods.test.integration_utils import BaseRemediationIntegrationTest
from core_codemods.harden_ruamel import HardenRuamel


class TestHardenRuamel(BaseIntegrationTest):
class TestHardenRuamel(BaseRemediationIntegrationTest):
codemod = HardenRuamel
original_code = """
from ruamel.yaml import YAML

serializer = YAML(typ="unsafe")
serializer = YAML(typ="base")
"""
replacement_lines = [
(3, 'serializer = YAML(typ="safe")\n'),
(4, 'serializer = YAML(typ="safe")\n'),
expected_diff_per_change = [
'--- \n+++ \n@@ -1,4 +1,4 @@\n from ruamel.yaml import YAML\n \n-serializer = YAML(typ="unsafe")\n+serializer = YAML(typ="safe")\n serializer = YAML(typ="base")',
'--- \n+++ \n@@ -1,4 +1,4 @@\n from ruamel.yaml import YAML\n \n serializer = YAML(typ="unsafe")\n-serializer = YAML(typ="base")\n+serializer = YAML(typ="safe")',
]
expected_diff = '--- \n+++ \n@@ -1,4 +1,4 @@\n from ruamel.yaml import YAML\n \n-serializer = YAML(typ="unsafe")\n-serializer = YAML(typ="base")\n+serializer = YAML(typ="safe")\n+serializer = YAML(typ="safe")\n'
expected_line_change = "3"

expected_lines_changed = [3, 4]
num_changes = 2
change_description = HardenRuamel.change_description
15 changes: 8 additions & 7 deletions integration_tests/test_jinja2_autoescape.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
from codemodder.codemods.test import BaseIntegrationTest
from codemodder.codemods.test.integration_utils import BaseRemediationIntegrationTest
from core_codemods.enable_jinja2_autoescape import (
EnableJinja2Autoescape,
EnableJinja2AutoescapeTransformer,
)


class TestEnableJinja2Autoescape(BaseIntegrationTest):
class TestEnableJinja2Autoescape(BaseRemediationIntegrationTest):
codemod = EnableJinja2Autoescape
original_code = """
from jinja2 import Environment

env = Environment()
env = Environment(autoescape=False)
"""
replacement_lines = [
(3, "env = Environment(autoescape=True)\n"),
(4, "env = Environment(autoescape=True)\n"),

expected_diff_per_change = [
"--- \n+++ \n@@ -1,4 +1,4 @@\n from jinja2 import Environment\n \n-env = Environment()\n+env = Environment(autoescape=True)\n env = Environment(autoescape=False)",
"--- \n+++ \n@@ -1,4 +1,4 @@\n from jinja2 import Environment\n \n env = Environment()\n-env = Environment(autoescape=False)\n+env = Environment(autoescape=True)",
]
expected_diff = "--- \n+++ \n@@ -1,4 +1,4 @@\n from jinja2 import Environment\n \n-env = Environment()\n-env = Environment(autoescape=False)\n+env = Environment(autoescape=True)\n+env = Environment(autoescape=True)\n"
expected_line_change = "3"

expected_lines_changed = [3, 4]
num_changes = 2
change_description = EnableJinja2AutoescapeTransformer.change_description
20 changes: 7 additions & 13 deletions integration_tests/test_jwt_decode_verify.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from codemodder.codemods.test import BaseIntegrationTest
from codemodder.codemods.test.integration_utils import BaseRemediationIntegrationTest
from core_codemods.jwt_decode_verify import JwtDecodeVerify, JwtDecodeVerifyTransformer


class TestJwtDecodeVerify(BaseIntegrationTest):
class TestJwtDecodeVerify(BaseRemediationIntegrationTest):
codemod = JwtDecodeVerify
original_code = """
import jwt
Expand All @@ -20,17 +20,11 @@ class TestJwtDecodeVerify(BaseIntegrationTest):

var = "something"
"""
replacement_lines = [
(
11,
"""decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], verify=True)\n""",
),
(
12,
"""decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], options={"verify_signature": True})\n""",
),
expected_diff_per_change = [
'--- \n+++ \n@@ -8,7 +8,7 @@\n \n encoded_jwt = jwt.encode(payload, SECRET_KEY, algorithm="HS256")\n \n-decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], verify=False)\n+decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], verify=True)\n decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], options={"verify_signature": False})\n \n var = "something"',
'--- \n+++ \n@@ -9,6 +9,6 @@\n encoded_jwt = jwt.encode(payload, SECRET_KEY, algorithm="HS256")\n \n decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], verify=False)\n-decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], options={"verify_signature": False})\n+decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], options={"verify_signature": True})\n \n var = "something"',
]
expected_diff = '--- \n+++ \n@@ -8,7 +8,7 @@\n \n encoded_jwt = jwt.encode(payload, SECRET_KEY, algorithm="HS256")\n \n-decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], verify=False)\n-decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], options={"verify_signature": False})\n+decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], verify=True)\n+decoded_payload = jwt.decode(encoded_jwt, SECRET_KEY, algorithms=["HS256"], options={"verify_signature": True})\n \n var = "something"\n'
expected_line_change = "11"

expected_lines_changed = [11, 12]
num_changes = 2
change_description = JwtDecodeVerifyTransformer.change_description
24 changes: 6 additions & 18 deletions integration_tests/test_lazy_logging.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,20 @@
from codemodder.codemods.test import BaseIntegrationTest
from codemodder.codemods.test.integration_utils import BaseRemediationIntegrationTest
from core_codemods.lazy_logging import LazyLogging


class TestLazyLogging(BaseIntegrationTest):
class TestLazyLogging(BaseRemediationIntegrationTest):
codemod = LazyLogging
original_code = """
import logging
e = "Some error"
logging.error("Error occurred: %s" % e)
logging.error("Error occurred: " + e)
"""
replacement_lines = [
(3, """logging.error("Error occurred: %s", e)\n"""),
(4, """logging.error("Error occurred: %s", e)\n"""),
expected_diff_per_change = [
'--- \n+++ \n@@ -1,4 +1,4 @@\n import logging\n e = "Some error"\n-logging.error("Error occurred: %s" % e)\n+logging.error("Error occurred: %s", e)\n logging.error("Error occurred: " + e)',
'--- \n+++ \n@@ -1,4 +1,4 @@\n import logging\n e = "Some error"\n logging.error("Error occurred: %s" % e)\n-logging.error("Error occurred: " + e)\n+logging.error("Error occurred: %s", e)',
]
# fmt: off
expected_diff = (
"""--- \n"""
"""+++ \n"""
"""@@ -1,4 +1,4 @@\n"""
""" import logging\n"""
""" e = "Some error"\n"""
"""-logging.error("Error occurred: %s" % e)\n"""
"""-logging.error("Error occurred: " + e)\n"""
"""+logging.error("Error occurred: %s", e)\n"""
"""+logging.error("Error occurred: %s", e)\n""")
# fmt: on

expected_line_change = "3"
expected_lines_changed = [3, 4]
change_description = LazyLogging.change_description
num_changes = 2
19 changes: 6 additions & 13 deletions integration_tests/test_lxml_safe_parsing.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
from codemodder.codemods.test import BaseIntegrationTest
from codemodder.codemods.test.integration_utils import BaseRemediationIntegrationTest
from core_codemods.lxml_safe_parsing import LxmlSafeParsing


class TestLxmlSafeParsing(BaseIntegrationTest):
class TestLxmlSafeParsing(BaseRemediationIntegrationTest):
codemod = LxmlSafeParsing
original_code = """
import lxml.etree
lxml.etree.parse("path_to_file")
lxml.etree.fromstring("xml_str")
"""
replacement_lines = [
(
2,
'lxml.etree.parse("path_to_file", parser=lxml.etree.XMLParser(resolve_entities=False))\n',
),
(
3,
'lxml.etree.fromstring("xml_str", parser=lxml.etree.XMLParser(resolve_entities=False))\n',
),
expected_lines_changed = [2, 3]
expected_diff_per_change = [
'--- \n+++ \n@@ -1,3 +1,3 @@\n import lxml.etree\n-lxml.etree.parse("path_to_file")\n+lxml.etree.parse("path_to_file", parser=lxml.etree.XMLParser(resolve_entities=False))\n lxml.etree.fromstring("xml_str")',
'--- \n+++ \n@@ -1,3 +1,3 @@\n import lxml.etree\n lxml.etree.parse("path_to_file")\n-lxml.etree.fromstring("xml_str")\n+lxml.etree.fromstring("xml_str", parser=lxml.etree.XMLParser(resolve_entities=False))',
]
expected_diff = '--- \n+++ \n@@ -1,3 +1,3 @@\n import lxml.etree\n-lxml.etree.parse("path_to_file")\n-lxml.etree.fromstring("xml_str")\n+lxml.etree.parse("path_to_file", parser=lxml.etree.XMLParser(resolve_entities=False))\n+lxml.etree.fromstring("xml_str", parser=lxml.etree.XMLParser(resolve_entities=False))\n'
expected_line_change = "2"
num_changes = 2
change_description = LxmlSafeParsing.change_description
allowed_exceptions = (OSError,)
Loading
Loading