Skip to content

Commit 7df3657

Browse files
aaronpowellCopilot
andauthored
fix: remove shell usage from plugin check (#1367)
* fix: remove shell usage from plugin check Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: harden plugin symlink scan Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent cfe4143 commit 7df3657

File tree

1 file changed

+45
-7
lines changed

1 file changed

+45
-7
lines changed

.github/workflows/check-plugin-structure.yml

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,50 @@ jobs:
2121
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
2222
with:
2323
script: |
24-
const { execSync } = require('child_process');
2524
const fs = require('fs');
2625
const path = require('path');
2726
2827
const pluginsDir = 'plugins';
2928
const errors = [];
3029
30+
function findSymlinks(rootDir) {
31+
const symlinks = [];
32+
const dirsToScan = [rootDir];
33+
34+
while (dirsToScan.length > 0) {
35+
const currentDir = dirsToScan.pop();
36+
let entries;
37+
38+
try {
39+
entries = fs.readdirSync(currentDir, { withFileTypes: true });
40+
} catch (error) {
41+
throw new Error(`Failed to read directory "${currentDir}": ${error.message}`);
42+
}
43+
44+
for (const entry of entries) {
45+
const entryPath = path.join(currentDir, entry.name);
46+
let stat;
47+
48+
try {
49+
stat = fs.lstatSync(entryPath);
50+
} catch (error) {
51+
throw new Error(`Failed to inspect "${entryPath}": ${error.message}`);
52+
}
53+
54+
if (stat.isSymbolicLink()) {
55+
symlinks.push(entryPath);
56+
continue;
57+
}
58+
59+
if (stat.isDirectory()) {
60+
dirsToScan.push(entryPath);
61+
}
62+
}
63+
}
64+
65+
return symlinks;
66+
}
67+
3168
if (!fs.existsSync(pluginsDir)) {
3269
console.log('No plugins directory found');
3370
return;
@@ -63,14 +100,15 @@ jobs:
63100
}
64101
}
65102
66-
// Check for symlinks anywhere in the plugin directory
103+
// Check for symlinks anywhere in the plugin directory without invoking a shell
67104
try {
68-
const allFiles = execSync(`find "${pluginPath}" -type l`, { encoding: 'utf-8' }).trim();
69-
if (allFiles) {
70-
errors.push(`${pluginPath} contains symlinks:\n${allFiles}`);
105+
const symlinkPaths = findSymlinks(pluginPath);
106+
if (symlinkPaths.length > 0) {
107+
const formattedPaths = symlinkPaths.map(filePath => `\`${filePath}\``).join(', ');
108+
errors.push(`${pluginPath} contains symlinks: ${formattedPaths}`);
71109
}
72-
} catch (e) {
73-
// find returns non-zero if no matches, ignore
110+
} catch (error) {
111+
errors.push(`Failed to inspect ${pluginPath} for symlinks: ${error.message}`);
74112
}
75113
}
76114

0 commit comments

Comments
 (0)