Skip to content

Commit 9ac85d8

Browse files
committed
Address also newlines in shared_memory names by encoding and decoding the names
1 parent e5f9549 commit 9ac85d8

2 files changed

Lines changed: 19 additions & 6 deletions

File tree

Lib/multiprocessing/resource_tracker.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
# this resource tracker process, "killall python" would probably leave unlinked
1616
# resources.
1717

18+
import base64
1819
import os
1920
import signal
2021
import sys
@@ -248,6 +249,12 @@ def _write(self, msg):
248249
assert nbytes == len(msg), f"{nbytes=} != {len(msg)=}"
249250

250251
def _send(self, cmd, name, rtype):
252+
# Encode shared_memory names as they are created by the user and may contain
253+
# colons or newlines.
254+
if rtype == "shared_memory":
255+
b = name.encode('utf-8', 'surrogateescape')
256+
name = base64.urlsafe_b64encode(b).decode('ascii')
257+
251258
msg = f"{cmd}:{name}:{rtype}\n".encode("ascii")
252259
if len(msg) > 512:
253260
# posix guarantees that writes to a pipe of less than PIPE_BUF
@@ -285,12 +292,13 @@ def main(fd):
285292
with open(fd, 'rb') as f:
286293
for line in f:
287294
try:
288-
parts = line.strip().decode('ascii').split(':')
289-
if len(parts) < 3:
290-
raise ValueError("malformed resource_tracker message: %r" % (parts,))
291-
cmd = parts[0]
292-
rtype = parts[-1]
293-
name = ':'.join(parts[1:-1])
295+
cmd, enc_name, rtype = line.rstrip(b'\n').decode('ascii').split(':', 2)
296+
if rtype == "shared_memory":
297+
name = base64.urlsafe_b64decode(enc_name.encode('ascii')).decode('utf-8', 'surrogateescape')
298+
else:
299+
# Semaphore names are generated internally, so no encoding is needed.
300+
name = enc_name
301+
294302
cleanup_func = _CLEANUP_FUNCS.get(rtype, None)
295303
if cleanup_func is None:
296304
raise ValueError(

Lib/test/_test_multiprocessing.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7353,6 +7353,11 @@ def test_that_shared_memory_name_with_colons_has_no_resource_tracker_errors(self
73537353
":starts:with:colon",
73547354
"ends:with:colon:",
73557355
"::double::colons::",
7356+
"name\\nwithnewline",
7357+
"name-with-trailing-newline\\n",
7358+
"\\nname-starts-with-newline",
7359+
"colons:and\\nnewlines:mix",
7360+
"multi\\nline\\nname",
73567361
]
73577362
73587363
for name in test_names:

0 commit comments

Comments
 (0)