Req #79220 [NEW]: Allow setting FFI_LIB search path at runtime

From: Date: Tue, 04 Feb 2020 11:47:27 +0000
Subject: Req #79220 [NEW]: Allow setting FFI_LIB search path at runtime
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-225345@lists.php.net to get a copy of this message
From: ojrask at gmail dot com Operating system: - PHP version: 7.4.2 Package: Dynamic loading Bug Type: Feature/Change Request Bug description:Allow setting FFI_LIB search path at runtime Description: ------------ Currently, when using the new FFI core extension, and loading dynamic libraries using the FFI_LIB header definition, the path is passed as is to dlopen(3). What this means is: 1. Absolute paths work as expected 2. Relative paths work from the current working directory (not changeable with PHP's chdir) 3. LD_LIBRARY_PATH works, but only if the PHP interpreter itself if invoked after adjusting the env var 4. /lib and /usr/lib work as expected. The problem this poses is as follows: Assume I want to create a new distributable PHP package, using Composer for instance. I want to bundle an FFI compatible dynamic library into the package itself. Now, when someone installs the package, the files will be installed under the vendor directory of the project root they are working in. Hence the library path becomes something similar to /home/user/projects/a/vendor/myvendor/mypkg/libs/lib.so. Now, when I want to use FFI::load, I am required to use the FFI_LIB define in my header file. If the lib.h lives inside the package's lib directory, next to the lib.so library binary, I must take the following into consideration: 1. Cannot use ./lib.so, as quite literally no one will run PHP from that directory 2. Cannot use absolute path, as there is no way of knowing it in advance 3. Cannot use LD_LIBRARY_PATH as that would require everyone to write their own wrappers for the PHP interpreter that sets the variable 4. Cannot use /lib, as I do not wish to pollute systems globally when installing a PHP package (Python has this problem by default, requiring juggling venvs 99% of the time) So the only "builtin" option is to use FFI::cdef. Is there any way to instruct the FFI extension to use additional search paths at runtime when loading libraries using the FFI_LIB definition? My current hack to fix this goes as follows: 1. Load the raw text contents of the lib.h file 2. Replace the FFI_LIB path with an absolutized path using preg_replace or similar 3. Put the altered contents into a temporary templib.h file somewhere accessible (e.g. /tmp) 4. Use that file instead of the real lib.h file when doing FFI::load(...). This works and allows setting an absolute path to a library file at runtime. But this is a little hacky and I would like to see an official and supported method to do this. Maybe something like ``` \FFI::setLibraryPaths(['/path/to/libs']); // maybe some ::resetLibraryPaths could exist as well // now dlopen should receive an absolute path to an /path/to/libs/lib.so file that was found, otherwise error out if not found, or maybe defer to regular dlopen logic $ffi = \FFI::load(__DIR__ . '/lib/lib.h'); // lib.h has `FFI_LIB "lib.so" defined ``` Things I don't know about: - Is my suggestion safe, as in do people understand what happens and what holes they might be opening up? Then again who knows how often malware and such can inject files into /lib in the first place. - Would it make a dent in loading performance, if we need to glob *.so files in X number of user supplied directories? - Or is this just an edge case and most of the time people will not be installing FFI Composer packages and hack together loading shims just like I did now? -- Edit bug report at https://bugs.php.net/bug.php?id=79220&edit=1 -- Fix committed: https://bugs.php.net/fix.php?id=79220&r=fixed Fixed in release: https://bugs.php.net/fix.php?id=79220&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=79220&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=79220&r=needscript Try newer version: https://bugs.php.net/fix.php?id=79220&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=79220&r=support Expected behavior: https://bugs.php.net/fix.php?id=79220&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=79220&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=79220&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=79220&r=globals PHP version support discontinued: https://bugs.php.net/fix.php?id=79220&r=phptooold Daylight Savings: https://bugs.php.net/fix.php?id=79220&r=dst IIS Stability: https://bugs.php.net/fix.php?id=79220&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=79220&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=79220&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=79220&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=79220&r=mysqlcfg

« previous php.bugs (#225345) next »