Skip to content

Commit 3eb1cbe

Browse files
committed
[GR-76124][GR-76125][GR-76126][GR-76127] Harden GraalPy helper code
PullRequest: graalpython/4592
2 parents 074401c + 5edb9c1 commit 3eb1cbe

4 files changed

Lines changed: 33 additions & 10 deletions

File tree

graalpython/com.oracle.graal.python.cext/include/graalpy/handles.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -74,7 +74,7 @@
7474
#define points_to_py_int_handle(PTR) (((uint64_t)(uintptr_t)(PTR)) & INTEGER_TAG_BIT)
7575
#define points_to_py_float_handle(PTR) (((uint64_t)(uintptr_t)(PTR)) & FLOAT_TAG_BIT)
7676

77-
#define stub_to_pointer(STUB_PTR) ((uintptr_t)(((uint64_t)(uintptr_t)(PTR)) | HANDLE_TAG_BIT))
77+
#define stub_to_pointer(STUB_PTR) ((uintptr_t)(((uint64_t)(uintptr_t)(STUB_PTR)) | HANDLE_TAG_BIT))
7878
#define int32_to_pointer(INT) ((uintptr_t)((((uint64_t)(uint32_t)(INT) << 3) & _35_BIT_MASK) | HANDLE_TAG_BIT | INTEGER_TAG_BIT))
7979
static inline PyObject* float_to_pointer(float dbl) {
8080
uint32_t float_bits;

graalpython/lib-graalpython/modules/standalone/__main__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
22
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
#
44
# The Universal Permissive License (UPL), Version 1.0
@@ -331,10 +331,15 @@ def get_tools(target_dir, parsed_args):
331331
if platform.system() == 'Darwin' or platform.system() == 'Linux':
332332
with tarfile.open(graalvm_file) as tar_file:
333333
first_member = tar_file.next().path
334-
tar_file.extractall(vm_path)
334+
try:
335+
tar_file.extractall(vm_path, filter="data")
336+
except TypeError:
337+
# older Python versions do not support filter, but the risk does not warrant a fallback implementation
338+
tar_file.extractall(vm_path)
335339
else:
336340
with zipfile.ZipFile(graalvm_file) as zip_file:
337341
first_member = zip_file.namelist()[0]
342+
# zipfile.extractall normalizes absolute paths and ".." components.
338343
zip_file.extractall(vm_path)
339344

340345
graalvm_dir = os.path.join(vm_path, first_member[:first_member.index("/")])

mx.graalpython/mx_graalpython.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,7 +1571,8 @@ def run_python_unittests(python_binary, args=None, paths=None, exclude=None, env
15711571
reportfile = None
15721572
t0 = time.time()
15731573
if report:
1574-
reportfile = os.path.abspath(tempfile.mktemp(prefix="test-report-", suffix=".json"))
1574+
with tempfile.NamedTemporaryFile(prefix="test-report-", suffix=".json", delete=False) as report_tmp:
1575+
reportfile = os.path.abspath(report_tmp.name)
15751576
args += ["--mx-report", reportfile]
15761577

15771578
if paths is not None:
@@ -2582,8 +2583,8 @@ def python_checkcopyrights(args):
25822583
files = args[i + 1:]
25832584
args = args[:i]
25842585
# we wan't to ignore lib-python/3, because that's just crazy
2585-
listfilename = tempfile.mktemp()
2586-
with open(listfilename, "w") as listfile:
2586+
with tempfile.NamedTemporaryFile("w", delete=False) as listfile:
2587+
listfilename = listfile.name
25872588
if files is None:
25882589
mx.run(["git", "ls-tree", "-r", "HEAD", "--name-only"], out=listfile)
25892590
else:
@@ -3299,15 +3300,26 @@ def run_mx(args, *splat, **kwargs):
32993300
return mx.run_mx(args, *splat, **kwargs)
33003301

33013302

3303+
def _parse_host_inlining_fields(fields):
3304+
parts = fields.split(":")
3305+
if len(parts) > 3:
3306+
raise ValueError("fields must be an integer index or slice")
3307+
result = int(fields) if len(parts) == 1 else slice(*(int(part) if part.strip() else None for part in parts))
3308+
if isinstance(result, slice) and result.step == 0:
3309+
raise ValueError("fields must be an integer index or slice")
3310+
return result
3311+
3312+
33023313
def host_inlining_log_extract_method(args_in):
33033314
parser = ArgumentParser(description="Extracts single method from host inlining log file. "
33043315
"Result, when saved to file, can be visualized with: java scripts/HostInliningVisualizer.java filename")
33053316
parser.add_argument("filename", help="file with host inlining log")
33063317
parser.add_argument("method", help="name of a method to extract")
3307-
parser.add_argument("-f", "--fields",
3318+
parser.add_argument("-f", "--fields", type=_parse_host_inlining_fields,
33083319
help="fields to select from the list with details, use Python subscript syntax, "
33093320
"default: '-1:' (i.e., the last field: reason for the [non-]inlining decision)", default="-1:")
33103321
args = parser.parse_args(args_in)
3322+
fields = args.fields
33113323

33123324
start = 'Context: HostedMethod<' + args.method + ' '
33133325
result = []
@@ -3326,7 +3338,8 @@ def host_inlining_log_extract_method(args_in):
33263338
match = re.search(r'\[inlined.*\]', line)
33273339
if match:
33283340
details = match.group().split(',')
3329-
details = ', '.join(eval(f"details[{args.fields}]")) #pylint: disable=eval-used
3341+
selected_details = details[fields]
3342+
details = ', '.join([selected_details] if isinstance(fields, int) else selected_details)
33303343
line = line[:match.start()].rstrip() + f' [{details}]'
33313344
for x in remove:
33323345
line = line.replace(x, '')

scripts/wheelbuilder/build_wheels.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,16 @@ def extract(archive):
8484
print("Extracting", archive, flush=True)
8585
if splitext(archive)[1] == ".zip":
8686
with zipfile.ZipFile(archive) as f:
87+
# zipfile.extractall normalizes absolute paths and ".." components.
8788
f.extractall()
8889
return f.infolist()[0].filename.split('/', 1)[0]
8990
else:
9091
with tarfile.open(archive) as f:
91-
f.extractall()
92+
try:
93+
f.extractall(filter="data")
94+
except TypeError:
95+
# older Python versions do not support filter, but the risk does not warrant a fallback implementation
96+
f.extractall()
9297
return f.getmembers()[0].name.split('/', 1)[0]
9398

9499

0 commit comments

Comments
 (0)