fix: on case-insensitive systems (Windows and Mac), it was not prevented showing 2 files with same name (in case one came from the disk and the other from the vfs)
Massimo Melina committed
Feb 25, 2024 at 17:36 UTC
fec007f451fa07423cd4a9e1a3f53c829fdc2e6f
1 file changed
+9
-5
src/vfs.ts
+9
-5
@@ -7,7 +7,7 @@ import { dirStream, enforceFinal, getOrSet, isDirectory, makeMatcher, setHidden,
7
import Koa from 'koa'
8
import _ from 'lodash'
9
import { defineConfig, setConfig } from './config'
10
-import { HTTP_FORBIDDEN, HTTP_UNAUTHORIZED, MIME_AUTO } from './const'
10
+import { HTTP_FORBIDDEN, HTTP_UNAUTHORIZED, IS_MAC, IS_WINDOWS, MIME_AUTO } from './const'
11
import events from './events'
12
import { expandUsername } from './perm'
13
import { getCurrentUsername } from './auth'
@@ -63,9 +63,13 @@ function inheritFromParent(parent: VfsNode, child: VfsNode) {
63
}
64
65
export function isSameFilenameAs(name: string) {
66
- const lc = name.toLowerCase()
66
+ const normalized = normalizeFilename(name)
67
return (other: string | VfsNode) =>
68
- lc === (typeof other === 'string' ? other : getNodeName(other)).toLowerCase()
68
+ normalized === normalizeFilename(typeof other === 'string' ? other : getNodeName(other))
69
+}
70
+
71
+function normalizeFilename(x: string) {
72
+ return IS_WINDOWS || IS_MAC ? x.toLocaleLowerCase() : x
73
}
74
75
export async function applyParentToChild(child: VfsNode | undefined, parent: VfsNode, name?: string) {
@@ -237,7 +241,7 @@ export async function* walkNode(parent: VfsNode, {
241
if (onlyFolders && !await nodeIsDirectory(child)) continue
242
const nodeName = getNodeName(child)
243
const name = prefixPath + nodeName
240
- took?.add(name)
244
+ took?.add(normalizeFilename(name))
245
const item = { ...child, name }
246
if (!canSee(item)) continue
247
if (item.source) // real items must be accessible
@@ -265,7 +269,7 @@ export async function* walkNode(parent: VfsNode, {
269
if (ctx?.req.aborted)
270
return
271
const name = prefixPath + (parent.rename?.[path] || path)
268
- if (took?.has(name)) continue
272
+ if (took?.has(normalizeFilename(name))) continue
273
if (depth) {
274
const dir = dirname(name)
275
if (dir !== lastDir)