



























@@ -158,6 +158,60 @@ export const SANDBOX_PINNED_MUTATION_PYTHON = [
158158" os.close(dir_fd)",
159159" os.rmdir(basename, dir_fd=parent_fd)",
160160"",
161+"def copy_entry(src_parent_fd, src_basename, dst_parent_fd, dst_basename):",
162+" src_stat = os.lstat(src_basename, dir_fd=src_parent_fd)",
163+" if stat.S_ISDIR(src_stat.st_mode) and not stat.S_ISLNK(src_stat.st_mode):",
164+" os.mkdir(dst_basename, stat.S_IMODE(src_stat.st_mode) or 0o755, dir_fd=dst_parent_fd)",
165+" src_dir_fd = None",
166+" dst_dir_fd = None",
167+" try:",
168+" src_dir_fd = open_dir(src_basename, dir_fd=src_parent_fd)",
169+" dst_dir_fd = open_dir(dst_basename, dir_fd=dst_parent_fd)",
170+" for child in os.listdir(src_dir_fd):",
171+" copy_entry(src_dir_fd, child, dst_dir_fd, child)",
172+" except Exception:",
173+" if dst_dir_fd is not None:",
174+" os.close(dst_dir_fd)",
175+" dst_dir_fd = None",
176+" try:",
177+" remove_tree(dst_parent_fd, dst_basename)",
178+" except FileNotFoundError:",
179+" pass",
180+" raise",
181+" finally:",
182+" if src_dir_fd is not None:",
183+" os.close(src_dir_fd)",
184+" if dst_dir_fd is not None:",
185+" os.close(dst_dir_fd)",
186+" return",
187+" if stat.S_ISLNK(src_stat.st_mode):",
188+" link_target = os.readlink(src_basename, dir_fd=src_parent_fd)",
189+" os.symlink(link_target, dst_basename, dir_fd=dst_parent_fd)",
190+" return",
191+" src_fd = os.open(src_basename, READ_FLAGS, dir_fd=src_parent_fd)",
192+" dst_fd = None",
193+" try:",
194+" src_file_stat = os.fstat(src_fd)",
195+" if not stat.S_ISREG(src_file_stat.st_mode):",
196+" raise OSError(errno.EPERM, 'only regular files are allowed', src_basename)",
197+" if src_file_stat.st_nlink > 1:",
198+" raise OSError(errno.EPERM, 'hardlinked file is not allowed', src_basename)",
199+" dst_fd = os.open(dst_basename, WRITE_FLAGS, stat.S_IMODE(src_stat.st_mode), dir_fd=dst_parent_fd)",
200+" while True:",
201+" chunk = os.read(src_fd, 65536)",
202+" if not chunk:",
203+" break",
204+" os.write(dst_fd, chunk)",
205+" try:",
206+" os.fchmod(dst_fd, stat.S_IMODE(src_stat.st_mode))",
207+" except AttributeError:",
208+" pass",
209+" os.fsync(dst_fd)",
210+" finally:",
211+" if dst_fd is not None:",
212+" os.close(dst_fd)",
213+" os.close(src_fd)",
214+"",
161215"def move_entry(src_parent_fd, src_basename, dst_parent_fd, dst_basename):",
162216" try:",
163217" os.rename(src_basename, dst_basename, src_dir_fd=src_parent_fd, dst_dir_fd=dst_parent_fd)",
@@ -170,16 +224,29 @@ export const SANDBOX_PINNED_MUTATION_PYTHON = [
170224" src_stat = os.lstat(src_basename, dir_fd=src_parent_fd)",
171225" if stat.S_ISDIR(src_stat.st_mode) and not stat.S_ISLNK(src_stat.st_mode):",
172226" temp_dir_name = create_temp_dir(dst_parent_fd, dst_basename, stat.S_IMODE(src_stat.st_mode) or 0o755)",
173-" temp_dir_fd = open_dir(temp_dir_name, dir_fd=dst_parent_fd)",
174-" src_dir_fd = open_dir(src_basename, dir_fd=src_parent_fd)",
227+" temp_dir_fd = None",
228+" src_dir_fd = None",
175229" try:",
230+" temp_dir_fd = open_dir(temp_dir_name, dir_fd=dst_parent_fd)",
231+" src_dir_fd = open_dir(src_basename, dir_fd=src_parent_fd)",
176232" for child in os.listdir(src_dir_fd):",
177-" move_entry(src_dir_fd, child, temp_dir_fd, child)",
178-" finally:",
233+" copy_entry(src_dir_fd, child, temp_dir_fd, child)",
179234" os.close(src_dir_fd)",
235+" src_dir_fd = None",
180236" os.close(temp_dir_fd)",
181-" os.rename(temp_dir_name, dst_basename, src_dir_fd=dst_parent_fd, dst_dir_fd=dst_parent_fd)",
182-" os.rmdir(src_basename, dir_fd=src_parent_fd)",
237+" temp_dir_fd = None",
238+" os.rename(temp_dir_name, dst_basename, src_dir_fd=dst_parent_fd, dst_dir_fd=dst_parent_fd)",
239+" except Exception:",
240+" if src_dir_fd is not None:",
241+" os.close(src_dir_fd)",
242+" if temp_dir_fd is not None:",
243+" os.close(temp_dir_fd)",
244+" try:",
245+" remove_tree(dst_parent_fd, temp_dir_name)",
246+" except FileNotFoundError:",
247+" pass",
248+" raise",
249+" remove_tree(src_parent_fd, src_basename)",
183250" os.fsync(dst_parent_fd)",
184251" os.fsync(src_parent_fd)",
185252" return",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。