Skip to content

Commit e1b6ec6

Browse files
authored
Add ruff and pre-commit (#23)
1 parent 5b33faa commit e1b6ec6

File tree

13 files changed

+177
-127
lines changed

13 files changed

+177
-127
lines changed

.pre-commit-config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
repos:
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.15.4
4+
hooks:
5+
- id: ruff-check
6+
args: [ --fix ]
7+
- id: ruff-format

pyproject.toml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,16 @@ pysoot = ["soot-trunk.jar"]
1515

1616
[dependency-groups]
1717
testing = ["pytest", "pytest-xdist"]
18-
dev = [{ include-group = "testing" }]
18+
dev = [
19+
{ include-group = "testing" },
20+
"ruff>=0.15.4",
21+
]
22+
23+
24+
[tool.ruff.lint]
25+
select = [
26+
"E",
27+
"F",
28+
"UP",
29+
"W",
30+
]

pysoot/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
from .lifter import Lifter
2+
3+
__all__ = ["Lifter"]

pysoot/errors.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
class PySootError(Exception):
32
pass
43

pysoot/lifter.py

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,21 @@
88
from .soot_manager import SootManager
99

1010

11-
l = logging.getLogger("pysoot.lifter")
11+
log = logging.getLogger("pysoot.lifter")
1212
self_dir = os.path.dirname(os.path.realpath(__file__))
1313

1414

15-
class Lifter(object):
16-
17-
def __init__(self, input_file=None, input_format="jar", ir_format="shimple", additional_jars=None,
18-
additional_jar_roots=None, android_sdk=None, save_to_file=None):
15+
class Lifter:
16+
def __init__(
17+
self,
18+
input_file=None,
19+
input_format="jar",
20+
ir_format="shimple",
21+
additional_jars=None,
22+
additional_jar_roots=None,
23+
android_sdk=None,
24+
save_to_file=None,
25+
):
1926

2027
self.input_file = os.path.realpath(input_file)
2128
self.save_to_file = save_to_file
@@ -31,47 +38,71 @@ def __init__(self, input_file=None, input_format="jar", ir_format="shimple", add
3138

3239
if input_format == "jar":
3340
if android_sdk is not None:
34-
l.warning("when input_format is 'jar', setting android_sdk is pointless")
41+
log.warning(
42+
"when input_format is 'jar', setting android_sdk is pointless"
43+
)
3544
absolute_library_jars = {_find_jrt_jar()}
3645
if additional_jars is not None:
37-
absolute_library_jars |= {os.path.realpath(jar) for jar in additional_jars}
46+
absolute_library_jars |= {
47+
os.path.realpath(jar) for jar in additional_jars
48+
}
3849
if additional_jar_roots is not None:
3950
for jar_root in additional_jar_roots:
4051
for jar_name in os.listdir(jar_root):
4152
if jar_name.endswith(".jar"):
42-
absolute_path = os.path.realpath(os.path.join(jar_root, jar_name))
53+
absolute_path = os.path.realpath(
54+
os.path.join(jar_root, jar_name)
55+
)
4356
if absolute_path not in absolute_library_jars:
4457
absolute_library_jars.add(absolute_path)
4558
seperator = ";" if os.name == "nt" else ":"
4659
bad_jars = [p for p in absolute_library_jars if seperator in p]
4760
if len(bad_jars) > 0:
48-
raise ParameterError("these jars have a semicolon in their name: " + repr(bad_jars))
61+
raise ParameterError(
62+
"these jars have a semicolon in their name: " + repr(bad_jars)
63+
)
4964
self.soot_classpath = seperator.join(absolute_library_jars)
5065

5166
elif input_format == "apk":
5267
if android_sdk is None:
53-
raise ParameterError("when format is apk, android_sdk should point to something like: "
54-
"~/Android/Sdk/platforms")
68+
raise ParameterError(
69+
"when format is apk, android_sdk should point to something like: "
70+
"~/Android/Sdk/platforms"
71+
)
5572
if additional_jars is not None or additional_jar_roots is not None:
56-
l.warning("when input_format is 'apk', setting additional_jars or additional_jar_roots is pointless")
73+
log.warning(
74+
"when input_format is 'apk', setting additional_jars or "
75+
"additional_jar_roots is pointless"
76+
)
5777
self.android_sdk = android_sdk
5878

5979
self._get_ir()
6080

6181
def _get_ir(self):
6282
config = {}
63-
settings = ["input_file", "input_format", "ir_format", "android_sdk", "soot_classpath", "main_class"]
83+
settings = [
84+
"input_file",
85+
"input_format",
86+
"ir_format",
87+
"android_sdk",
88+
"soot_classpath",
89+
"main_class",
90+
]
6491
for s in settings:
6592
config[s] = str(getattr(self, s, None))
6693

6794
self.soot_wrapper = SootManager()
6895

69-
l.info("Running Soot with the following config: " + repr(config))
96+
log.info("Running Soot with the following config: " + repr(config))
7097
self.soot_wrapper.init(**config)
7198
if self.save_to_file is None:
7299
self.classes = self.soot_wrapper.get_classes()
73100
else:
74-
ipc_options = {'return_result': False, 'return_pickle': False, 'save_pickle': self.save_to_file}
101+
ipc_options = {
102+
"return_result": False,
103+
"return_pickle": False,
104+
"save_pickle": self.save_to_file,
105+
}
75106
self.classes = self.soot_wrapper.get_classes(_ipc_options=ipc_options)
76107

77108

@@ -81,13 +112,13 @@ def _get_java_home() -> str:
81112
return os.environ["JAVA_HOME"]
82113

83114
# Command to get Java properties
84-
command = ["java", '-XshowSettings:properties', '-version']
115+
command = ["java", "-XshowSettings:properties", "-version"]
85116
# Execute the command and capture the output
86117
result = subprocess.run(command, capture_output=True, text=True)
87118
# Extract JAVA_HOME from the output
88119
for line in result.stderr.splitlines():
89120
if "java.home" in line:
90-
return line.split('=')[1].strip()
121+
return line.split("=")[1].strip()
91122

92123
raise JavaNotFoundError
93124

pysoot/soot_manager.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,20 @@ class SootManager:
2222
def __init__(self, java_heap_size: int | None = None):
2323
if java_heap_size is None:
2424
# use 75% of total memory for the Java heap
25-
self.java_heap_size = int(psutil.virtual_memory().total*0.75)
25+
self.java_heap_size = int(psutil.virtual_memory().total * 0.75)
2626
else:
2727
self.java_heap_size = java_heap_size
2828
startJVM()
2929

30-
31-
def init(self, main_class, input_file, input_format: str, android_sdk: str | None, soot_classpath: str | None, ir_format: str):
30+
def init(
31+
self,
32+
main_class,
33+
input_file,
34+
input_format: str,
35+
android_sdk: str | None,
36+
soot_classpath: str | None,
37+
ir_format: str,
38+
):
3239
Collections = JClass("java.util.Collections")
3340

3441
G = JClass("soot.G")
@@ -81,12 +88,16 @@ def get_classes(self):
8188
classes = {}
8289
for raw_class in self.raw_classes:
8390
# TODO with this we only get classes for which we have all the code
84-
# soot also has classes with lower "resolving levels", but for those we may not have
85-
# the method list or the code, if we want them we cannot fully translate them
91+
# soot also has classes with lower "resolving levels", but for those we may
92+
# not have the method list or the code, if we want them we cannot fully
93+
# translate them
8694
if raw_class.isApplicationClass():
8795
soot_class = SootClass.from_ir(raw_class)
8896
classes[soot_class.name] = soot_class
8997
return classes
9098

9199
def getSubclassesOf(self, class_name: str) -> list[str]:
92-
return [c.getName() for c in self.hierarchy.getSubclassesOf(self.class_name_map[class_name])]
100+
return [
101+
c.getName()
102+
for c in self.hierarchy.getSubclassesOf(self.class_name_map[class_name])
103+
]

pysoot/sootir/soot_block.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@ class SootBlock:
1212
idx: int | None
1313

1414
def __repr__(self):
15-
return "<Block %d [%d], %d statements>" % (
16-
self.idx if self.idx is not None else -1,
17-
self.label,
18-
len(self.statements),
19-
)
15+
idx = self.idx if self.idx is not None else -1
16+
return f"<Block {idx} [{self.label}], {len(self.statements)} statements>"
2017

2118
def __str__(self):
2219
tstr = "//" + repr(self) + "\n"

pysoot/sootir/soot_class.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,10 @@ def from_ir(ir_class):
7777
else:
7878
super_class = ""
7979
return SootClass(
80-
class_name, super_class, tuple(interface_names), tuple(attrs), tuple(methods), frozendict(fields)
80+
class_name,
81+
super_class,
82+
tuple(interface_names),
83+
tuple(attrs),
84+
tuple(methods),
85+
frozendict(fields),
8186
)

0 commit comments

Comments
 (0)