fix: folder listing stuck if one element had an endless-loop permission
Massimo Melina committed
Jun 16, 2024 at 18:54 UTC
7d96d3ccdae9f9f444650816e2ed52f6a8f3d10d
2 files changed
+30
-8
src/log.ts
+1
-1
@@ -106,7 +106,7 @@ export const logMw: Koa.Middleware = async (ctx, next) => {
106
renameSync(path, newPath)
107
}
108
catch(e: any) { // ok, rename failed, but this doesn't mean we ain't gonna log
109
- console.error(String(e || e.message))
109
+ console.error(e.message || String(e))
110
}
111
stream = logger.reopen() // keep variable updated
112
if (!stream) return
src/vfs.ts
+29
-7
@@ -2,8 +2,25 @@
2
3
import fs from 'fs/promises'
4
import { basename, dirname, join, resolve } from 'path'
5
-import { dirStream, enforceFinal, getOrSet, isDirectory, makeMatcher, setHidden, onlyTruthy, isValidFileName,
6
- throw_, VfsPerms, Who, isWhoObject, WHO_ANY_ACCOUNT, defaultPerms, PERM_KEYS, removeStarting } from './misc'
5
+import {
6
+ dirStream,
7
+ getOrSet,
8
+ isDirectory,
9
+ makeMatcher,
10
+ setHidden,
11
+ onlyTruthy,
12
+ isValidFileName,
13
+ throw_,
14
+ VfsPerms,
15
+ Who,
16
+ isWhoObject,
17
+ WHO_ANY_ACCOUNT,
18
+ defaultPerms,
19
+ PERM_KEYS,
20
+ removeStarting,
21
+ HTTP_SERVER_ERROR,
22
+ try_
23
+} from './misc'
24
import Koa from 'koa'
25
import _ from 'lodash'
26
import { defineConfig, setConfig } from './config'
@@ -204,14 +221,19 @@ export function statusCodeForMissingPerm(node: VfsNode, perm: keyof VfsPerms, ct
221
// calculate value of permission resolving references to other permissions, avoiding infinite loop
222
let who: Who | undefined
223
let max = PERM_KEYS.length
224
+ let cur = perm
225
do {
208
- who = node[perm]
226
+ who = node[cur]
227
if (isWhoObject(who))
228
who = who.this
211
- who ??= defaultPerms[perm]
212
- if (!max-- || typeof who !== 'string' || who === WHO_ANY_ACCOUNT)
229
+ who ??= defaultPerms[cur]
230
+ if (typeof who !== 'string' || who === WHO_ANY_ACCOUNT)
231
break
214
- perm = who
232
+ if (!max--) {
233
+ console.error(`endless loop in permission ${perm}=${node[perm] ?? defaultPerms[perm]} for ${node.url || getNodeName(node)}`)
234
+ return HTTP_SERVER_ERROR
235
+ }
236
+ cur = who
237
} while (1)
238
239
if (Array.isArray(who)) {
@@ -223,7 +245,7 @@ export function statusCodeForMissingPerm(node: VfsNode, perm: keyof VfsPerms, ct
245
}
246
return typeof who === 'boolean' ? (who ? 0 : HTTP_FORBIDDEN)
247
: who === WHO_ANY_ACCOUNT ? (getCurrentUsername(ctx) ? 0 : HTTP_UNAUTHORIZED)
226
- : throw_(Error('invalid permission: ' + JSON.stringify(who)))
248
+ : throw_(Error(`invalid permission: ${perm}=${try_(() => JSON.stringify(who))}`))
249
}
250
}
251