Req #79220 [NEW]: Allow setting FFI_LIB search path at runtime
| From: | ojrask at gmail dot com | 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