Skip to content

Commit 0093ecf

Browse files
committed
fix(sdk): harden the docs bundler against bad nav paths and empty output
Validate each docs.json nav path before joining (reject `..`/absolute so a fat-fingered entry cannot copy files from outside docs/), and fail the build if zero docs were copied rather than shipping an empty docs bundle.
1 parent 93851d5 commit 0093ecf

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

scripts/bundleSdkDocs.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,14 @@ async function bundleSdkDocs() {
7676
let copied = 0;
7777

7878
for (const rel of manifest) {
79-
const src = path.join(docsRoot, `${rel}.mdx`);
79+
// Defensive: nav paths come from our own docs.json, but a fat-fingered `../` entry
80+
// shouldn't be able to copy a file from outside docs/ into the package.
81+
const safeRel = path.posix.normalize(rel);
82+
if (path.isAbsolute(safeRel) || safeRel.startsWith("..")) {
83+
throw new Error(`[bundleSdkDocs] invalid nav path "${rel}" under "${DROPDOWN}"`);
84+
}
85+
86+
const src = path.join(docsRoot, `${safeRel}.mdx`);
8087
try {
8188
await fs.access(src);
8289
} catch {
@@ -85,7 +92,7 @@ async function bundleSdkDocs() {
8592
missing.push(rel);
8693
continue;
8794
}
88-
const dest = path.join(outDir, `${rel}.mdx`);
95+
const dest = path.join(outDir, `${safeRel}.mdx`);
8996
await fs.mkdir(path.dirname(dest), { recursive: true });
9097
await fs.copyFile(src, dest);
9198
copied++;
@@ -98,6 +105,11 @@ async function bundleSdkDocs() {
98105
);
99106
}
100107

108+
if (copied === 0) {
109+
// Every nav page was missing on disk; refuse to ship the SDK with an empty docs bundle.
110+
throw new Error(`[bundleSdkDocs] 0 docs copied from the "${DROPDOWN}" nav; refusing empty docs bundle`);
111+
}
112+
101113
console.log(
102114
`[bundleSdkDocs] bundled ${copied} docs from the "${DROPDOWN}" nav into ${path.relative(
103115
repoRoot,

0 commit comments

Comments
 (0)