fix: admin couldn't list files in drive's root on Windows

Massimo Melina committed Feb 9, 2022 at 19:37 UTC 9157c88ba8e02dc6a524fd2139be2bb7d2d50622
3 files changed +20 -19
src/api.vfs.ts
+15 -19
@@ -4,8 +4,8 @@ import { stat } from 'fs/promises'
4 import { ApiError, ApiHandlers } from './apis'
5 import { dirname } from 'path'
6 import { saveConfigAsap } from './config'
7 -import glob from 'fast-glob'
8 -import { enforceFinal, isWindows } from './misc'
7 +import glob, { Entry } from 'fast-glob'
8 +import { enforceFinal, isWindows, isWindowsDrive } from './misc'
9 import { exec } from 'child_process'
10 import { promisify } from 'util'
11
@@ -106,32 +106,28 @@ const apis: ApiHandlers = {
106 return
107 }
108 try {
109 + if (isWindowsDrive(path))
110 + path = enforceFinal('/', path)
111 const dirStream = glob.stream('*', {
112 cwd: path,
113 dot: true,
114 onlyFiles: false,
115 + stats: true,
116 })
114 - const base = enforceFinal('/', path)
115 - for await (let path of dirStream) {
117 + for await (const entry of dirStream) {
118 if (ctx.req.aborted)
119 return
118 - if (path instanceof Buffer)
119 - path = path.toString('utf8')
120 - try {
121 - const stats = await stat(base + path)
122 - yield {
123 - add: {
124 - n: path,
125 - s: stats.size,
126 - c: stats.ctime,
127 - m: stats.mtime,
128 - k: stats.isDirectory() ? 'd' : undefined,
129 - }
120 + let { name, stats } = entry as any as Entry
121 + if (!stats) continue
122 + yield {
123 + add: {
124 + n: name,
125 + s: stats.size,
126 + c: stats.ctime,
127 + m: stats.mtime,
128 + k: stats.isDirectory() ? 'd' : undefined,
129 }
130 }
132 - catch {
133 - console.debug('ls: failed stat for ', path)
134 - }
131 }
132 } catch (e) {
133 if ((e as any).code !== 'ENOTDIR')
src/misc.ts
+4
@@ -178,3 +178,7 @@ export function debounceAsync(cb: any, ms: number=100, ...args:any[]) {
178 export function dirTraversal(s?: string) {
179 return s && /(^|[/\\])\.\.($|[/\\])/.test(s)
180 }
181 +
182 +export function isWindowsDrive(s?: string) {
183 + return s && /^[a-zA-Z]:$/.test(s)
184 +}
todo.md
+1
@@ -1,4 +1,5 @@
1 # To do
2 +- password protect admin
3 - allowed referer
4 - admin/plugins
5 - download-counter: expose results on admin