@motionstudies/data 0.1.0-alpha.29 → 0.1.0-alpha.30

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@motionstudies/data",
3
- "version": "0.1.0-alpha.29",
3
+ "version": "0.1.0-alpha.30",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Offline data preparation primitives for Motion Studies.",
@@ -133,7 +133,7 @@
133
133
  ],
134
134
  "sideEffects": false,
135
135
  "dependencies": {
136
- "@motionstudies/core": "0.1.0-alpha.29",
136
+ "@motionstudies/core": "0.1.0-alpha.30",
137
137
  "fast-xml-parser": "5.11.1"
138
138
  }
139
139
  }
package/release-files.mjs CHANGED
@@ -6,12 +6,17 @@ import { checkReleaseManifest, digestHex, isReleasePath, readDescriptor, release
6
6
  export { readOperationalFile }
7
7
  const inside = (root, path) => { const r = relative(root, path); return r !== '' && !r.startsWith(`..${sep}`) && r !== '..' && !isAbsolute(r) }
8
8
 
9
- /** Read one described file from a release directory: safe path, no escape through links, bounded, size and digest checked. */
9
+ /**
10
+ * Read one described file from a release directory: safe path, bounded, size and digest checked. No component below
11
+ * the release root may be a symbolic link, even one pointing elsewhere inside it, so a described path always names
12
+ * exactly the file that was written there.
13
+ */
10
14
  export async function readReleaseFile(root, descriptor, { maxBytes = 512 * 1024 ** 2 } = {}) {
11
15
  const d = readDescriptor(descriptor)
12
16
  if (d.bytes > maxBytes) throw new Error(`${d.path} exceeds the read limit`)
13
- const base = await realpath(resolve(root)), actual = await realpath(join(base, ...d.path.split('/')))
17
+ const base = await realpath(resolve(root)), target = join(base, ...d.path.split('/')), actual = await realpath(target)
14
18
  if (!inside(base, actual)) throw new Error(`${d.path} resolves outside the release`)
19
+ if (actual !== target) throw new Error(`${d.path} passes through a symbolic link`)
15
20
  return verifyDescriptorBytes(await readOperationalFile(actual, d.bytes), d)
16
21
  }
17
22