|
15 | 15 | # this resource tracker process, "killall python" would probably leave unlinked |
16 | 16 | # resources. |
17 | 17 |
|
| 18 | +import base64 |
18 | 19 | import os |
19 | 20 | import signal |
20 | 21 | import sys |
@@ -248,6 +249,12 @@ def _write(self, msg): |
248 | 249 | assert nbytes == len(msg), f"{nbytes=} != {len(msg)=}" |
249 | 250 |
|
250 | 251 | 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 | + |
251 | 258 | msg = f"{cmd}:{name}:{rtype}\n".encode("ascii") |
252 | 259 | if len(msg) > 512: |
253 | 260 | # posix guarantees that writes to a pipe of less than PIPE_BUF |
@@ -285,12 +292,13 @@ def main(fd): |
285 | 292 | with open(fd, 'rb') as f: |
286 | 293 | for line in f: |
287 | 294 | 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 | + |
294 | 302 | cleanup_func = _CLEANUP_FUNCS.get(rtype, None) |
295 | 303 | if cleanup_func is None: |
296 | 304 | raise ValueError( |
|
0 commit comments