GeezerVison is showing github.com — vfs: reject rename into descendant directory · nodejs/node@d5f01bb
File treeExpand file treeCollapse file tree Open diff view settings lib/internal/vfs/providers
Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/vfs/providers/memory.js +6Lines changed: 6 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 7 | 7 | SafeMap, | 8 | 8 | SafeSet, | 9 | 9 | StringPrototypeReplaceAll, | | 10 | + StringPrototypeStartsWith, | 10 | 11 | Symbol, | 11 | 12 | } = primordials; | 12 | 13 |
| @@ -794,6 +795,11 @@ class MemoryProvider extends VirtualProvider { | 794 | 795 | // Get the entry (without following symlinks for the entry itself) | 795 | 796 | const entry = this.#getEntry(normalizedOld, 'rename', false); | 796 | 797 |
| | 798 | + if (entry.isDirectory() && | | 799 | + StringPrototypeStartsWith(normalizedNew, `${normalizedOld}/`)) { | | 800 | + throw createEINVAL('rename', oldPath); | | 801 | + } | | 802 | + | 797 | 803 | // Validate destination parent exists (do not auto-create) | 798 | 804 | const newParent = this.#ensureParent(normalizedNew, false, 'rename'); | 799 | 805 | const newName = pathPosix.basename(normalizedNew); | |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-vfs-rename.js +14Lines changed: 14 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -44,3 +44,17 @@ const vfs = require('node:vfs'); | 44 | 44 | assert.strictEqual(myVfs.existsSync('/d/a.txt'), false); | 45 | 45 | assert.strictEqual(myVfs.existsSync('/d/b.txt'), true); | 46 | 46 | } | | 47 | + | | 48 | +// Renaming a directory into its own descendant throws EINVAL | | 49 | +{ | | 50 | + const myVfs = vfs.create(); | | 51 | + myVfs.mkdirSync('/a/b', { recursive: true }); | | 52 | + myVfs.writeFileSync('/a/file.txt', 'data'); | | 53 | + | | 54 | + assert.throws(() => myVfs.renameSync('/a', '/a/b/c'), { code: 'EINVAL' }); | | 55 | + assert.deepStrictEqual(myVfs.readdirSync('/'), ['a']); | | 56 | + assert.strictEqual(myVfs.existsSync('/a'), true); | | 57 | + assert.strictEqual(myVfs.existsSync('/a/b'), true); | | 58 | + assert.strictEqual(myVfs.existsSync('/a/b/c'), false); | | 59 | + assert.strictEqual(myVfs.readFileSync('/a/file.txt', 'utf8'), 'data'); | | 60 | +} |
|