Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/com/google/javascript/jscomp/CompilerOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -1165,8 +1165,18 @@ void addReportGenerator(SortingErrorManager.ErrorReportGenerator generator) {
/**
* Whether to resolve source mapping annotations. Cannot do this in an appengine or js environment
* since we don't have access to the filesystem.
*/
private boolean resolveSourceMapAnnotations = true;
*
* <p>Defaults to {@code false}. When enabled, a {@code //# sourceMappingURL=} comment in
* compiled JS is followed to a file on the local filesystem (see {@link
* SourceMapResolver#extractSourceMap}), including via relative paths such as {@code
* ../../../../etc/passwd} that resolve outside the directory of the file being compiled. If
* this defaulted to {@code true}, compiling untrusted or third-party JavaScript source (e.g. in
* a hosted minification service or CI environment) would let the input JS trigger an arbitrary
* local file read with no explicit opt-in required. Callers who need to resolve source mapping
* annotations over source they fully trust can opt back in with {@link
* #setResolveSourceMapAnnotations}.
*/
private boolean resolveSourceMapAnnotations = false;

private ImmutableList<? extends SourceMap.LocationMapping> sourceMapLocationMappings =
ImmutableList.of();
Expand Down
9 changes: 9 additions & 0 deletions test/com/google/javascript/jscomp/CompilerOptionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@
@RunWith(JUnit4.class)
public final class CompilerOptionsTest {

@Test
public void testResolveSourceMapAnnotationsDefaultsToFalse() {
CompilerOptions options = new CompilerOptions();
assertThat(options.getResolveSourceMapAnnotations()).isFalse();

options.setResolveSourceMapAnnotations(true);
assertThat(options.getResolveSourceMapAnnotations()).isTrue();
}

@Test
public void testBrowserFeaturesetYearOptionSetsLanguageOut() {
CompilerOptions options = new CompilerOptions();
Expand Down
8 changes: 8 additions & 0 deletions test/com/google/javascript/jscomp/CompilerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ function X(input) {
public void testInputSourceMapInline() {
Compiler compiler = new Compiler();
compiler.initCompilerOptionsIfTesting();
compiler.getOptions().setResolveSourceMapAnnotations(true);
String code = SOURCE_MAP_TEST_CODE + "\n//# sourceMappingURL=" + BASE64_ENCODED_SOURCE_MAP;
CompilerInput input = new CompilerInput(SourceFile.fromCode("tmp", code));
input.getAstRoot(compiler);
Expand Down Expand Up @@ -290,6 +291,7 @@ function A(input) {
public void testInputSourceMapInlineContent() {
Compiler compiler = new Compiler();
compiler.initCompilerOptionsIfTesting();
compiler.getOptions().setResolveSourceMapAnnotations(true);
String code =
SOURCE_MAP_TEST_CODE + "\n//# sourceMappingURL=" + BASE64_ENCODED_SOURCE_MAP_WITH_CONTENT;
CompilerInput input = new CompilerInput(SourceFile.fromCode("tmp", code));
Expand All @@ -305,6 +307,7 @@ public void testInputSourceMapInlineContent() {
public void testResolveRelativeSourceMap() throws Exception {
Compiler compiler = new Compiler();
compiler.initCompilerOptionsIfTesting();
compiler.getOptions().setResolveSourceMapAnnotations(true);
File tempDir = Files.createTempDir();
String code = SOURCE_MAP_TEST_CODE + "\n//# sourceMappingURL=foo.js.map";
File jsFile = new File(tempDir, "foo.js");
Expand All @@ -330,6 +333,7 @@ public void testResolveRelativeSourceMap() throws Exception {
public void testResolveRelativeDirSourceMap() throws Exception {
Compiler compiler = new Compiler();
compiler.initCompilerOptionsIfTesting();
compiler.getOptions().setResolveSourceMapAnnotations(true);
File tempDir = Files.createTempDir();
File relativedir = new File(tempDir, "/relativedir");
relativedir.mkdir();
Expand All @@ -356,6 +360,7 @@ public void testResolveRelativeDirSourceMap() throws Exception {
public void testMissingSourceMapFile() throws Exception {
Compiler compiler = new Compiler();
compiler.initCompilerOptionsIfTesting();
compiler.getOptions().setResolveSourceMapAnnotations(true);
File tempDir = Files.createTempDir();
String code = SOURCE_MAP_TEST_CODE + "\n//# sourceMappingURL=foo-does-not-exist.js.map";
File jsFile = new File(tempDir, "foo2.js");
Expand Down Expand Up @@ -434,6 +439,7 @@ public void testKeepInputSourceMapsSourcesContent() throws Exception {
options.setLanguageIn(LanguageMode.ECMASCRIPT3);
options.setSourceMapOutputPath("fake/source_map_path.js.map");
options.setApplyInputSourceMaps(true);
options.setResolveSourceMapAnnotations(true);
options.setSourceMapIncludeSourcesContent(true);
String code =
SOURCE_MAP_TEST_CODE + "\n//# sourceMappingURL=" + BASE64_ENCODED_SOURCE_MAP_WITH_CONTENT;
Expand Down Expand Up @@ -1563,6 +1569,7 @@ public void testCheckSaveRestore3StagesSourceMaps() throws Exception {
// maps when running the final stage later.
options.setAlwaysGatherSourceMapInfo(true);
options.setApplyInputSourceMaps(true);
options.setResolveSourceMapAnnotations(true);
options.setSourceMapIncludeSourcesContent(true);
CompilationLevel.ADVANCED_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
List<SourceFile> externs =
Expand Down Expand Up @@ -1650,6 +1657,7 @@ public void testSingleStageCompileSourceMaps() throws Exception {
// path is stored in this field.
options.setSourceMapOutputPath("dummy");
options.setApplyInputSourceMaps(true);
options.setResolveSourceMapAnnotations(true);
options.setSourceMapIncludeSourcesContent(true);
CompilationLevel.ADVANCED_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
List<SourceFile> externs =
Expand Down