Skip to content

Commit d5846a0

Browse files
committed
[FIX] FileSystem Adapter: Prevent "Maximum call stack size exceeded"
Fixes: UI5/cli#1088
1 parent e40a1bd commit d5846a0

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

lib/adapters/FileSystem.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ class FileSystem extends AbstractAdapter {
138138
}
139139
const results = await Promise.all(promises);
140140

141-
// Flatten results
142-
return Array.prototype.concat.apply([], results).filter(($) => $);
141+
// Remove 'null' results
142+
return results.filter(($) => $);
143143
}
144144

145145
/**

test/lib/adapters/FileSystem_read.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import sinon from "sinon";
33
import esmock from "esmock";
44
import path from "node:path";
55
import {createAdapter} from "../../../lib/resourceFactory.js";
6+
import {fileURLToPath} from "node:url";
7+
import Resource from "../../../lib/Resource.js";
68

79
test("glob resources from application.a w/ virtual base path prefix", async (t) => {
810
const readerWriter = createAdapter({
@@ -582,3 +584,50 @@ test("byPath with useGitignore: true", async (t) => {
582584

583585
t.is(isGitIgnoredSpy.callCount, 1, "isGitIgnored should only be called once per FileSystem instance");
584586
});
587+
588+
test("byGlob with a larger number of results", async (t) => {
589+
const globbyStub = sinon.stub().callsFake(async (_patterns, _options) => {
590+
return Array.from({length: 1_000_000}).map((_, i) => `/file${i}.js`);
591+
});
592+
593+
const fakeStat = {
594+
isFile: () => true,
595+
isDirectory: () => false
596+
};
597+
598+
const FileSystem = await esmock("../../../lib/adapters/FileSystem.js", {
599+
"globby": {
600+
globby: globbyStub,
601+
isGitIgnored: async () => false
602+
},
603+
"graceful-fs": {
604+
stat: ((filePath, cb) => {
605+
if (filePath.startsWith(fsBasePath)) {
606+
cb(null, fakeStat);
607+
} else {
608+
cb({code: "ENOENT"});
609+
}
610+
})
611+
}
612+
});
613+
614+
const fsBasePath = fileURLToPath(new URL("../../tmp/virtual/large-project/", import.meta.url));
615+
616+
const reader = new FileSystem({
617+
fsBasePath,
618+
virBasePath: "/"
619+
});
620+
621+
const resources = await reader.byGlob("/**/*.js");
622+
623+
t.is(resources.length, 1_000_000);
624+
625+
// Picking just one resource in between for testing
626+
const resource = resources[500_000];
627+
628+
t.true(resource instanceof Resource, "Resource should be an instance of Resource");
629+
t.true(
630+
resource.getPath().startsWith("/file") && resource.getPath().endsWith(".js"),
631+
"Resource should have correct path"
632+
);
633+
});

0 commit comments

Comments
 (0)