Skip to content

Commit 92f757d

Browse files
Thanatos9404alan-agius4
authored andcommitted
fix(@angular-devkit/schematics): do not ignore TypeErrors thrown by content templates
Since 18.1.0 (41ee8ea), `applyContentTemplate` returns the entry unchanged for any `TypeError`, so that content which is not valid UTF-8 is left alone. Decoding and applying the template shared one `try`, so a `TypeError` thrown by the template itself, such as `<%= name.length %>` with `name` undefined, also left the file unrendered without an error. Decode in a separate `try` so that only decode failures are ignored.
1 parent cea0b42 commit 92f757d

2 files changed

Lines changed: 20 additions & 6 deletions

File tree

‎packages/angular_devkit/schematics/src/rules/template.ts‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,9 @@ export function applyContentTemplate<T>(options: T): FileOperator {
5454
return (entry: FileEntry) => {
5555
const { path, content } = entry;
5656

57+
let decodedContent: string;
5758
try {
58-
const decodedContent = decoder.decode(content).replace(/\r?\n/g, EOL);
59-
60-
return {
61-
path,
62-
content: Buffer.from(templateImpl(decodedContent, {})(options)),
63-
};
59+
decodedContent = decoder.decode(content);
6460
} catch (e) {
6561
// The second part should not be needed. But Jest does not support instanceof correctly.
6662
// See: https://github.com/jestjs/jest/issues/2549
@@ -73,6 +69,12 @@ export function applyContentTemplate<T>(options: T): FileOperator {
7369

7470
throw e;
7571
}
72+
decodedContent = decodedContent.replace(/\r?\n/g, EOL);
73+
74+
return {
75+
path,
76+
content: Buffer.from(templateImpl(decodedContent, {})(options)),
77+
};
7678
};
7779
}
7880

‎packages/angular_devkit/schematics/src/rules/template_spec.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,18 @@ describe('contentTemplate', () => {
171171
expect(_applyContentTemplate('a<%= \'a\' + "b" %>b', {})).toBe('aabb');
172172
expect(_applyContentTemplate('a<%= "\\n" + "b" %>b', {})).toBe('a\nbb');
173173
});
174+
175+
it('does not ignore type errors thrown by a template', () => {
176+
expect(() => _applyContentTemplate('a<%= value.length %>b', { value: undefined })).toThrowError(
177+
/Cannot read properties of undefined/,
178+
);
179+
});
180+
181+
it('leaves content that is not valid UTF-8 unchanged', () => {
182+
const entry = { path: normalize('/a/b/image.png'), content: Buffer.from([0xff, 0xfe, 0xfd]) };
183+
184+
expect(applyContentTemplate({})(entry)).toBe(entry);
185+
});
174186
});
175187

176188
describe('applyTemplateFiles', () => {

0 commit comments

Comments
 (0)