From 5d8f7da3aa42174954798b263fe559e55fbc435f Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Thu, 27 Feb 2020 19:50:14 +0000 Subject: [PATCH] refactor(ngcc): guard against a crash if source-map flattening fails (#35718) Source-maps in the wild could be badly formatted, causing the source-map flattening processing to fail unexpectedly. Rather than causing the whole of ngcc to crash, we gracefully fallback to just returning the generated source-map instead. PR Close #35718 --- .../ngcc/src/rendering/dts_renderer.ts | 2 +- .../ngcc/src/rendering/renderer.ts | 2 +- .../ngcc/src/rendering/source_maps.ts | 40 ++++++++++++------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/packages/compiler-cli/ngcc/src/rendering/dts_renderer.ts b/packages/compiler-cli/ngcc/src/rendering/dts_renderer.ts index de7f5bfa73..746145f689 100644 --- a/packages/compiler-cli/ngcc/src/rendering/dts_renderer.ts +++ b/packages/compiler-cli/ngcc/src/rendering/dts_renderer.ts @@ -111,7 +111,7 @@ export class DtsRenderer { this.dtsFormatter.addImports( outputText, importManager.getAllImports(dtsFile.fileName), dtsFile); - return renderSourceAndMap(this.fs, dtsFile, outputText); + return renderSourceAndMap(this.logger, this.fs, dtsFile, outputText); } private getTypingsFilesToRender( diff --git a/packages/compiler-cli/ngcc/src/rendering/renderer.ts b/packages/compiler-cli/ngcc/src/rendering/renderer.ts index 54fa472b6c..54480b7df7 100644 --- a/packages/compiler-cli/ngcc/src/rendering/renderer.ts +++ b/packages/compiler-cli/ngcc/src/rendering/renderer.ts @@ -114,7 +114,7 @@ export class Renderer { } if (compiledFile || switchMarkerAnalysis || isEntryPoint) { - return renderSourceAndMap(this.fs, sourceFile, outputText); + return renderSourceAndMap(this.logger, this.fs, sourceFile, outputText); } else { return []; } diff --git a/packages/compiler-cli/ngcc/src/rendering/source_maps.ts b/packages/compiler-cli/ngcc/src/rendering/source_maps.ts index e198278a2d..ff836bdc60 100644 --- a/packages/compiler-cli/ngcc/src/rendering/source_maps.ts +++ b/packages/compiler-cli/ngcc/src/rendering/source_maps.ts @@ -12,6 +12,7 @@ import {FileSystem, absoluteFromSourceFile, basename, absoluteFrom} from '../../ import {FileToWrite} from './utils'; import {SourceFileLoader} from '../sourcemaps/source_file_loader'; import {RawSourceMap} from '../sourcemaps/raw_source_map'; +import {Logger} from '../logging/logger'; export interface SourceMapInfo { source: string; @@ -24,28 +25,39 @@ export interface SourceMapInfo { * with an appropriate source-map comment pointing to the merged source-map. */ export function renderSourceAndMap( - fs: FileSystem, sourceFile: ts.SourceFile, generatedMagicString: MagicString): FileToWrite[] { + logger: Logger, fs: FileSystem, sourceFile: ts.SourceFile, + generatedMagicString: MagicString): FileToWrite[] { const generatedPath = absoluteFromSourceFile(sourceFile); const generatedMapPath = absoluteFrom(`${generatedPath}.map`); const generatedContent = generatedMagicString.toString(); const generatedMap: RawSourceMap = generatedMagicString.generateMap( {file: generatedPath, source: generatedPath, includeContent: true}); - const loader = new SourceFileLoader(fs); - const generatedFile = loader.loadSourceFile( - generatedPath, generatedContent, {map: generatedMap, mapPath: generatedMapPath}); + try { + const loader = new SourceFileLoader(fs); + const generatedFile = loader.loadSourceFile( + generatedPath, generatedContent, {map: generatedMap, mapPath: generatedMapPath}); - const rawMergedMap: RawSourceMap = generatedFile.renderFlattenedSourceMap(); - const mergedMap = fromObject(rawMergedMap); - - if (generatedFile.sources[0]?.inline) { - // The input source-map was inline so make the output one inline too. - return [{path: generatedPath, contents: `${generatedFile.contents}\n${mergedMap.toComment()}`}]; - } else { - const sourceMapComment = generateMapFileComment(`${basename(generatedPath)}.map`); + const rawMergedMap: RawSourceMap = generatedFile.renderFlattenedSourceMap(); + const mergedMap = fromObject(rawMergedMap); + if (generatedFile.sources[0]?.inline) { + // The input source-map was inline so make the output one inline too. + return [ + {path: generatedPath, contents: `${generatedFile.contents}\n${mergedMap.toComment()}`} + ]; + } else { + const sourceMapComment = generateMapFileComment(`${basename(generatedPath)}.map`); + return [ + {path: generatedPath, contents: `${generatedFile.contents}\n${sourceMapComment}`}, + {path: generatedMapPath, contents: mergedMap.toJSON()} + ]; + } + } catch (e) { + logger.error( + `Error when flattening the source-map "${generatedMapPath}" for "${generatedPath}": ${e.toString()}`); return [ - {path: generatedPath, contents: `${generatedFile.contents}\n${sourceMapComment}`}, - {path: generatedMapPath, contents: mergedMap.toJSON()} + {path: generatedPath, contents: generatedContent}, + {path: generatedMapPath, contents: fromObject(generatedMap).toJSON()}, ]; } }