fix: faulty negative deep masks like "!**/*.png"
Massimo Melina committed
Mar 27, 2025 at 12:47 UTC
8e2c6e7a4ed68bc15ed00d1dcc2c66e7924b5e1e
3 files changed
+10
-2
src/vfs.ts
+3
-1
@@ -399,6 +399,7 @@ export function masksCouldGivePermission(masks: Masks | undefined, perm: keyof V
399
}
400
401
export function parentMaskApplier(parent: VfsNode) {
402
+ // rules are met in the parent.masks object from nearest to farthest, but since we finally apply with _.defaults, the nearest has precedence in the final result
403
const matchers = onlyTruthy(_.map(parent.masks, (mods, k) => {
404
if (!mods) return
405
const mustBeFolder = (() => { // undefined if no restriction is requested
@@ -409,7 +410,8 @@ export function parentMaskApplier(parent: VfsNode) {
410
k = k.slice(0, i) // remove
411
return type === 'folders'
412
})()
412
- k = k.startsWith('**/') ? k.slice(3) : !k.includes('/') ? k : '' // ** globstar matches also zero subfolders, so this mask must be applied here too
413
+ const m = /^(!?)\*\*\//.exec(k) // ** globstar matches also zero subfolders, so this mask must be applied here too
414
+ k = m ? m[1] + k.slice(m[0].length) : !k.includes('/') ? k : ''
415
return k && { mods, matcher: makeMatcher(k), mustBeFolder }
416
}))
417
return async (item: VfsNode, virtualBasename=basename(getNodeName(item))) => { // we basename for depth>0
tests/config.yaml
+3
@@ -49,6 +49,9 @@ vfs:
49
can_list:
50
- disabled_account
51
- source: tests
52
+ masks:
53
+ "!**/*.png|files|":
54
+ can_see: false
55
- name: renameChild
56
children:
57
- source: tests
tests/test.ts
+4
-1
@@ -111,6 +111,7 @@ describe('basics', () => {
111
112
it('protectFromAbove', req('/protectFromAbove/child/alfa.txt', 403))
113
it('protectFromAbove.list', reqList('/protectFromAbove/child/', { inList:['alfa.txt'] }))
114
+ it('inheritNegativeMask', reqList('/tests/page', { outList: ['index.html'] }))
115
116
const zipSize = 13010
117
const zipOfs = 0x1359
@@ -327,7 +328,9 @@ function req(url: string, test:Tester, { baseUrl, throttle, ...requestOptions }:
328
const data = await stream2string(stream)
329
const obj = tryJson(data)
330
if (typeof test === 'object') {
330
- const { status, mime, re, inList, outList, length, permInList } = test
331
+ let { status, mime, re, inList, outList, length, permInList } = test
332
+ if (inList || outList)
333
+ status ||= 200
334
const gotMime = res.headers?.['content-type']
335
const gotStatus = res.statusCode
336
const gotLength = res.headers?.['content-length']