Skip to content

(GH-141) Fix renaming a dir with sub-directories#320

Closed
da-ar wants to merge 2 commits into
spf13:masterfrom
da-ar:fix-mem-rename
Closed

(GH-141) Fix renaming a dir with sub-directories#320
da-ar wants to merge 2 commits into
spf13:masterfrom
da-ar:fix-mem-rename

Conversation

@da-ar

@da-ar da-ar commented Sep 2, 2021

Copy link
Copy Markdown

This is an update to #239 to address the open comments, and rebased off master

@CLAassistant

CLAassistant commented Sep 2, 2021

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@jxsl13

jxsl13 commented Jan 9, 2022

Copy link
Copy Markdown

what happens if you have got
two sub directories called

/subdir1/whatever/
/subdir10/whatever1/

and you try to rename subdir1?

@spf13

spf13 commented May 7, 2026

Copy link
Copy Markdown
Owner

The fix is in the right direction but has two bugs that need addressing before this can merge:

  1. Data race in the range loop. You're doing a lock upgrade (RUnlock → Lock → mutate → Unlock → RLock) inside a range over the same map you're mutating. This is a data race: the range iterator's internal state is invalidated by the concurrent mutation. Collect the keys to rename first, then mutate in a second pass:

    // collect under read lock
    m.mu.RLock()
    var toRename []string
    for p := range m.getData() {
        if strings.HasPrefix(p, oldname+"/") || p == oldname {
            toRename = append(toRename, p)
        }
    }
    m.mu.RUnlock()
    // mutate under write lock
    m.mu.Lock()
    for _, p := range toRename {
        newP := newname + p[len(oldname):]
        m.getData()[newP] = m.getData()[p]
        delete(m.getData(), p)
    }
    m.mu.Unlock()
  2. Prefix collision. strings.HasPrefix(p, oldname) matches /subdir10 when renaming /subdir1. The prefix check must be strings.HasPrefix(p, oldname+"/") (or normalizePath(oldname)+FilePathSeparator).

Fix both and this is mergeable.

@spf13

spf13 commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Thanks for this — the bug you identified was real. However, this fix is now already in the codebase via renameDescendants(), which was added in a subsequent commit and handles this case correctly (and avoids the path-prefix collision that would affect your HasPrefix check, e.g. renaming /src incorrectly matching /src-other). Closing as already fixed.

@spf13 spf13 closed this Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants