Skip to content

Commit

Permalink
Check that source files are in the project directory for AutoCopy.
Browse files Browse the repository at this point in the history
  • Loading branch information
zachleat committed Dec 6, 2024
1 parent 92ca693 commit daedbcc
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 10 deletions.
27 changes: 18 additions & 9 deletions src/TemplatePassthrough.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class TemplatePassthrough {
#isInputPathGlob;
#benchmarks;
#isAlreadyNormalized = false;
#projectDirCheck = false;

// paths already guaranteed from the autocopy plugin
static factory(inputPath, outputPath, opts = {}) {
Expand All @@ -30,10 +31,6 @@ class TemplatePassthrough {
opts.templateConfig,
);

if (opts.normalized) {
p.setIsAlreadyNormalized(true);
}

return p;
}

Expand Down Expand Up @@ -70,6 +67,10 @@ class TemplatePassthrough {
return this.templateConfig.getConfig();
}

get directories() {
return this.templateConfig.directories;
}

// inputDir is used when stripping from output path in `getOutputPath`
get inputDir() {
return this.templateConfig.directories.input;
Expand All @@ -84,6 +85,10 @@ class TemplatePassthrough {
this.#isAlreadyNormalized = Boolean(isNormalized);
}

setCheckSourceDirectory(check) {
this.#projectDirCheck = Boolean(check);
}

/* { inputPath, outputPath } though outputPath is *not* the full path: just the output directory */
getPath() {
return this.rawPath;
Expand Down Expand Up @@ -241,11 +246,15 @@ class TemplatePassthrough {
* 3. individual file
*/
async copy(src, dest, copyOptions) {
if (
!TemplatePath.stripLeadingDotSlash(dest).startsWith(
TemplatePath.stripLeadingDotSlash(this.outputDir),
)
) {
if (this.#projectDirCheck && !this.directories.isFileInProjectFolder(src)) {
return Promise.reject(
new TemplatePassthroughError(
"Source file is not in the project directory. Check your passthrough paths.",
),
);
}

if (!this.directories.isFileInOutputFolder(dest)) {
return Promise.reject(
new TemplatePassthroughError(
"Destination is not in the site output directory. Check your passthrough paths.",
Expand Down
3 changes: 2 additions & 1 deletion src/TemplatePassthroughManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,10 +325,11 @@ class TemplatePassthroughManager {

let passthrough = TemplatePassthrough.factory(source, target, {
templateConfig: this.templateConfig,
normalized: true,
copyOptions,
});

passthrough.setCheckSourceDirectory(true);
passthrough.setIsAlreadyNormalized(true);
passthrough.setRunMode(this.runMode);
passthrough.setDryRun(this.#isDryRun);

Expand Down
8 changes: 8 additions & 0 deletions src/Util/ProjectDirectories.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,14 @@ class ProjectDirectories {
);
}

isFileInProjectFolder(filePath) {
return TemplatePath.absolutePath(filePath).startsWith(TemplatePath.getWorkingDir());
}

isFileInOutputFolder(filePath) {
return TemplatePath.absolutePath(filePath).startsWith(TemplatePath.absolutePath(this.output));
}

// Access the data without being able to set the data.
getUserspaceInstance() {
let d = this;
Expand Down
23 changes: 23 additions & 0 deletions test/ProjectDirectoriesTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -347,3 +347,26 @@ test("getLayoutPath (includes dir)", t => {
t.is(d.getLayoutPath("layout.html"), "./test/stubs/components/layout.html");
t.is(d.getLayoutPathRelativeToInputDirectory("layout.html"), "components/layout.html");
});

test("isFileIn*Folder", t => {
let d = new ProjectDirectories();

t.is(d.isFileInProjectFolder("test.njk"), true);
t.is(d.isFileInProjectFolder("../test.njk"), false);

t.is(d.isFileInOutputFolder("test.njk"), false);
t.is(d.isFileInOutputFolder("../test.njk"), false);
t.is(d.isFileInOutputFolder("../_site/test.html"), false);
t.is(d.isFileInOutputFolder("_site/test.html"), true);
});

test("isFileInOutputFolder (change output folder)", t => {
let d = new ProjectDirectories();
d.setOutput("yolo")

t.is(d.isFileInOutputFolder("test.njk"), false);
t.is(d.isFileInOutputFolder("../test.njk"), false);
t.is(d.isFileInOutputFolder("_site/test.html"), false);
t.is(d.isFileInOutputFolder("../_site/test.html"), false);
t.is(d.isFileInOutputFolder("yolo/test.html"), true);
});

0 comments on commit daedbcc

Please sign in to comment.