






















@@ -158,6 +158,22 @@ export const SANDBOX_PINNED_MUTATION_PYTHON = [
158158" os.close(dir_fd)",
159159" os.rmdir(basename, dir_fd=parent_fd)",
160160"",
161+"def entry_identity(entry_stat):",
162+" return (",
163+" entry_stat.st_dev,",
164+" entry_stat.st_ino,",
165+" entry_stat.st_mode,",
166+" entry_stat.st_size,",
167+" getattr(entry_stat, 'st_mtime_ns', int(entry_stat.st_mtime * 1000000000)),",
168+" getattr(entry_stat, 'st_ctime_ns', int(entry_stat.st_ctime * 1000000000)),",
169+" )",
170+"",
171+"def same_identity(expected, entry_stat):",
172+" return expected == entry_identity(entry_stat)",
173+"",
174+"def source_changed_error(basename):",
175+" return OSError(getattr(errno, 'ESTALE', errno.EIO), 'source changed during move fallback cleanup', basename)",
176+"",
161177"def copy_entry(src_parent_fd, src_basename, dst_parent_fd, dst_basename):",
162178" src_stat = os.lstat(src_basename, dir_fd=src_parent_fd)",
163179" if stat.S_ISDIR(src_stat.st_mode) and not stat.S_ISLNK(src_stat.st_mode):",
@@ -167,6 +183,7 @@ export const SANDBOX_PINNED_MUTATION_PYTHON = [
167183" dst_dir_fd = None",
168184" try:",
169185" src_dir_fd = open_dir(src_basename, dir_fd=src_parent_fd)",
186+" src_stat = os.fstat(src_dir_fd)",
170187" dst_dir_fd = open_dir(dst_basename, dir_fd=dst_parent_fd)",
171188" for child in os.listdir(src_dir_fd):",
172189" copied_children.append((child, copy_entry(src_dir_fd, child, dst_dir_fd, child)))",
@@ -184,11 +201,11 @@ export const SANDBOX_PINNED_MUTATION_PYTHON = [
184201" os.close(src_dir_fd)",
185202" if dst_dir_fd is not None:",
186203" os.close(dst_dir_fd)",
187-" return ('dir', copied_children)",
204+" return ('dir', entry_identity(src_stat), copied_children)",
188205" if stat.S_ISLNK(src_stat.st_mode):",
189206" link_target = os.readlink(src_basename, dir_fd=src_parent_fd)",
190207" os.symlink(link_target, dst_basename, dir_fd=dst_parent_fd)",
191-" return ('leaf', None)",
208+" return ('leaf', entry_identity(src_stat), None)",
192209" src_fd = os.open(src_basename, READ_FLAGS, dir_fd=src_parent_fd)",
193210" dst_fd = None",
194211" try:",
@@ -212,10 +229,13 @@ export const SANDBOX_PINNED_MUTATION_PYTHON = [
212229" if dst_fd is not None:",
213230" os.close(dst_fd)",
214231" os.close(src_fd)",
215-" return ('leaf', None)",
232+" return ('leaf', entry_identity(src_file_stat), None)",
216233"",
217234"def remove_copied_entry(parent_fd, basename, manifest):",
218-" kind, children = manifest",
235+" kind, expected_identity, children = manifest",
236+" current_stat = os.lstat(basename, dir_fd=parent_fd)",
237+" if not same_identity(expected_identity, current_stat):",
238+" raise source_changed_error(basename)",
219239" if kind != 'dir':",
220240" os.unlink(basename, dir_fd=parent_fd)",
221241" return",
@@ -245,6 +265,7 @@ export const SANDBOX_PINNED_MUTATION_PYTHON = [
245265" try:",
246266" temp_dir_fd = open_dir(temp_dir_name, dir_fd=dst_parent_fd)",
247267" src_dir_fd = open_dir(src_basename, dir_fd=src_parent_fd)",
268+" src_stat = os.fstat(src_dir_fd)",
248269" for child in os.listdir(src_dir_fd):",
249270" copied_children.append((child, copy_entry(src_dir_fd, child, temp_dir_fd, child)))",
250271" os.close(src_dir_fd)",
@@ -262,7 +283,7 @@ export const SANDBOX_PINNED_MUTATION_PYTHON = [
262283" except FileNotFoundError:",
263284" pass",
264285" raise",
265-" remove_copied_entry(src_parent_fd, src_basename, ('dir', copied_children))",
286+" remove_copied_entry(src_parent_fd, src_basename, ('dir', entry_identity(src_stat), copied_children))",
266287" os.fsync(dst_parent_fd)",
267288" os.fsync(src_parent_fd)",
268289" return",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。