Skip to content

Commit 476e647

Browse files
committed
Narrow down the follow: false argument to php functions that call FS.stat
1 parent 706c100 commit 476e647

File tree

1 file changed

+28
-23
lines changed

1 file changed

+28
-23
lines changed

packages/php-wasm/node/src/lib/load-runtime.ts

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -96,30 +96,30 @@ export async function loadNodeRuntime(
9696
* for the path and Emscripten will accept it as if it was the real link path.
9797
*/
9898
if (options?.followSymlinks === true) {
99-
/**
100-
* By default, Emscripten will not follow symlinks when it's the final path component.
101-
* This behavior can cause issues in PHP-wasm when the caller requires the symlink to be followed,
102-
* but the PHP-wasm call to lookupPath didn't explicitly set follow to true.
103-
*
104-
* To ensure symlinks are followed by default when symlink following is enabled in PHP-wasm,
105-
* we override the `lookupPath` function and set follow to true.
106-
*
107-
* PHP and Emscripten functions can still override the default behavior
108-
* by setting follow to false which is required for function calls like lstat.
109-
*/
110-
const lookupPath = phpRuntime.FS.lookupPath;
111-
phpRuntime.FS.lookupPath = (
112-
path: string,
113-
options: any = {}
114-
) => {
115-
return lookupPath(path, {
116-
...options,
99+
const fsStat = phpRuntime.FS.stat;
100+
phpRuntime.FS.stat = (path: string, dontFollow: boolean) => {
101+
if (dontFollow === true && path.includes('woocommerce')) {
102+
const obj: any = {};
103+
if ('captureStackTrace' in Error) {
104+
Error.captureStackTrace(obj);
105+
}
106+
const stack = obj.stack.split('\n');
107+
const lastStackLine = stack[stack.length - 1];
108+
const functionName = lastStackLine.trim().split(' ')[1];
109+
117110
/**
118-
* If follow is true, a symlinked plugin will successfully be mounted during boot.
119-
* But that would break POSIX compatibility because callers need to be able to not follow symlinks.
111+
* One of these functions is called with dontFollow set to true
112+
* and causes plugin activation to fail with a "Plugin file does not exist" error.
113+
*
114+
* Potentially related to https://core.trac.wordpress.org/ticket/16953
120115
*/
121-
// follow: true,
122-
});
116+
dontFollow = ![
117+
'php.wasm.php_stat',
118+
'php.wasm.__fstatat',
119+
'php.wasm.tsrm_realpath_r',
120+
].includes(functionName);
121+
}
122+
return fsStat(path, dontFollow);
123123
};
124124

125125
phpRuntime.FS.filesystems.NODEFS.node_ops.readlink = (
@@ -155,7 +155,12 @@ export async function loadNodeRuntime(
155155
{ root: absoluteSourcePath },
156156
symlinkPath
157157
);
158-
console.log('\n[DEBUG] readlink mounted symlinked path', absoluteSourcePath, '->', symlinkPath);
158+
console.log(
159+
'\n[DEBUG] readlink mounted symlinked path',
160+
absoluteSourcePath,
161+
'->',
162+
symlinkPath
163+
);
159164
}
160165
return symlinkPath;
161166
};

0 commit comments

Comments
 (0)