Description
The Dart process execute search prefers the current directory over a PATH search. This behavior violates the rule of least surprise and doesn't appear to be documented. It should instead simply do a path search.
This example program demonstrates the issue:
import 'dart:io';
main() {
print(Process.runSync("tar", ["--version"]).stdout);
}
This normally works if the system tar is first in the PATH, but if the current directory contains an executable file named tar
, then that is preferred even when the current directory is not in the PATH.
#!/bin/sh
echo Preferred the current directory
If that file exists, the test instead prints Preferred the current directory
because it preferred the current directory even though it was not in the PATH.
This seems related to the dart --namespace option. The issue seems to be in runtime/bin/process_linux.cc
and runtime/bin/process_android.cc
in ProcessStarter::ExecProcess
and ProcessStarter::ExecDetachedProcess
char realpath[PATH_MAX];
if (!FindPathInNamespace(realpath, PATH_MAX)) {
ReportChildError();
}
// TODO(dart:io) Test for the existence of execveat, and use it instead.
VOID_TEMP_FAILURE_RETRY(
execvp(realpath, const_cast<char* const*>(program_arguments_)));
The intention of the namespace feature seems to be to emulate a different root directory and working directory, possibly per isolate. The PATH search in the namespace case doesn't seem to be implemented at all, where only absolute paths work. I'll understand what the code is trying to do a bit closer and then come up with a proper fix.
cc @jonasfj