Skip to content

Commit 858c4d6

Browse files
test(@angular/build): add output path boundary checks
1 parent 0190945 commit 858c4d6

2 files changed

Lines changed: 54 additions & 0 deletions

File tree

packages/angular/build/src/builders/application/tests/options/output-path_spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,22 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
260260
}),
261261
);
262262
});
263+
264+
it('should error when the output path escapes the workspace root', async () => {
265+
harness.useTarget('build', {
266+
...BASE_OPTIONS,
267+
polyfills: [],
268+
outputPath: '../dist',
269+
});
270+
271+
const { result, error } = await harness.executeOnce({
272+
outputLogsOnException: false,
273+
outputLogsOnFailure: false,
274+
});
275+
276+
expect(result).toBeUndefined();
277+
expect(error?.message).toMatch(/must be inside the project root directory/);
278+
});
263279
});
264280
});
265281
});
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
10+
import { tmpdir } from 'node:os';
11+
import { join } from 'node:path';
12+
import { deleteOutputDir } from './delete-output-dir';
13+
14+
describe('deleteOutputDir', () => {
15+
let workspaceRoot: string;
16+
17+
beforeEach(async () => {
18+
workspaceRoot = await mkdtemp(join(tmpdir(), 'angular-cli-test-'));
19+
await mkdir(join(workspaceRoot, 'dist'), { recursive: true });
20+
await writeFile(join(workspaceRoot, 'dist', 'file.txt'), 'test');
21+
});
22+
23+
afterEach(async () => {
24+
await rm(workspaceRoot, { recursive: true, force: true });
25+
});
26+
27+
it('should reject deleting the project root directory', async () => {
28+
await expectAsync(deleteOutputDir(workspaceRoot, '.')).toBeRejectedWithError(
29+
'Output path MUST not be project root directory!',
30+
);
31+
});
32+
33+
it('should reject deleting a path outside the project root', async () => {
34+
await expectAsync(deleteOutputDir(workspaceRoot, '..')).toBeRejectedWithError(
35+
new RegExp(`Output path '.*' MUST be inside the project root '${workspaceRoot}'.`),
36+
);
37+
});
38+
});

0 commit comments

Comments
 (0)