@jeffusion/bungee-types 4.5.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/daemon-file.js +29 -1
- package/package.json +1 -1
package/dist/daemon-file.js
CHANGED
|
@@ -52,6 +52,28 @@ function contained(parent, child, platform) {
|
|
|
52
52
|
const target = comparePath(child, platform);
|
|
53
53
|
return target !== root && target.startsWith(`${root}/`);
|
|
54
54
|
}
|
|
55
|
+
function withoutWindowsNamespacePrefix(value) {
|
|
56
|
+
return value.replace(/^\\\\\?\\UNC\\/i, '\\\\').replace(/^\\\\\?\\/i, '');
|
|
57
|
+
}
|
|
58
|
+
async function windowsContainmentDiagnostic(root, target, canonical, initial) {
|
|
59
|
+
let lstatState = 'error';
|
|
60
|
+
let identityState = 'unavailable';
|
|
61
|
+
let linkState = 'unavailable';
|
|
62
|
+
try {
|
|
63
|
+
const current = await lstat(target);
|
|
64
|
+
lstatState = current.isSymbolicLink() ? 'symlink' : current.isFile() ? 'regular' : 'non_regular';
|
|
65
|
+
identityState = sameIdentity(identity(initial), identity(current)) ? 'same' : 'changed';
|
|
66
|
+
linkState = current.nlink === 0 ? 'zero' : current.nlink === 1 ? 'single' : 'multiple';
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (error.code === 'ENOENT')
|
|
70
|
+
lstatState = 'missing';
|
|
71
|
+
}
|
|
72
|
+
const namespaceState = comparePath(withoutWindowsNamespacePrefix(canonical), 'win32')
|
|
73
|
+
=== comparePath(withoutWindowsNamespacePrefix(join(root, METADATA_FILENAME)), 'win32')
|
|
74
|
+
? 'equivalent' : 'different';
|
|
75
|
+
return `metadata file escaped the runtime root; windows_realpath_containment=escaped lstat=${lstatState} identity=${identityState} nlink=${linkState} namespace_prefix=${namespaceState}`;
|
|
76
|
+
}
|
|
55
77
|
function sameIdentity(left, right) {
|
|
56
78
|
return left.dev === right.dev && left.ino === right.ino;
|
|
57
79
|
}
|
|
@@ -190,8 +212,14 @@ async function secureTarget(targetPath, options, mustExist) {
|
|
|
190
212
|
await ensureWindowsAcl(target, options.windowsAcl ?? defaultWindowsAclAdapter(), 'file', options);
|
|
191
213
|
testStage(options, 'target_realpath');
|
|
192
214
|
const canonical = await realpath(target);
|
|
193
|
-
if (!contained(canonicalRoot, canonical, platform))
|
|
215
|
+
if (!contained(canonicalRoot, canonical, platform)) {
|
|
216
|
+
if (platform === 'win32') {
|
|
217
|
+
const error = new DaemonFileError('containment', 'metadata file escaped the runtime root');
|
|
218
|
+
error.message = await windowsContainmentDiagnostic(canonicalRoot, target, canonical, item);
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
194
221
|
fail('containment', 'metadata file escaped the runtime root');
|
|
222
|
+
}
|
|
195
223
|
return { root: canonicalRoot, target, initial: identity(item) };
|
|
196
224
|
}
|
|
197
225
|
catch (error) {
|