Skip to content

[RenameFile] Rename can overwrite/delete files; crash on null job queue #798

Open

Description

@dude-stash

Plugin: RenameFile (1.0.3)

Data loss: a rename can overwrite another file of the same scene

os.rename() and shutil.move() silently replace an existing file on POSIX. rename_scene computes the new name and checks targetDidExist, but never refuses to rename onto it.

This happens with scenes that have more than one file (for example an h264 and an h265 version). The plugin only ever works on files[0], and builds the name from the scene's metadata. If another file of the scene already has that name, for example because it was renamed earlier when it was the only file, the rename replaces it and that file is gone from disk. I hit this and have confirmed it.

The failure handling can also delete files. After a failed rename, if new_file_path exists, os.remove(original_file_path) is called without checking that the two paths are different files. The delayed-deletion loop has the same problem. On a case-insensitive mount, a case-only rename that raises would delete the only copy.

Crash: 'NoneType' object is not iterable

stash.job_queue() can return None. Only tooManyScanOnTaskQueue guards against that. Every other taskQueue helper loops over it, so the plugin aborts:

File "renamefile.py", line 372, in rename_scene
  if not os.path.isfile(original_file_path) and not taskqueue.clearDupTagsJobOnTaskQueue() ...
File "StashPluginHelper.py", line 1156, in isRunningPluginTaskJobOnTaskQueue
  for jobDetails in self.taskqueue:
TypeError: 'NoneType' object is not iterable

Also, isRunningPluginTaskJobOnTaskQueue compares against "Running plugin task: {taskName}" without the f prefix, so it never matches.

Max Tag Keys has no effect

The limit is only checked in add_tag(), which nothing calls. The tags field uses getTags(), which joins every tag, so the setting is ignored.

Fix

See the linked PR. It normalises a None job queue to [], fixes the f-string, picks a free name (N) when the target (or an associated file target) exists, removes both os.remove calls, and applies Max Tag Keys in getTags(). With it, the second file of a scene gets name (2) and the first file is left alone.

Not covered: renaming every file of a multi-file scene. The plugin still only renames files[0].

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions