From:  pear-qa@lists.php.net ("phpbug@monumentmail.com")
Date:  31 Jan 2015 19:33:54 Hong Kong Time
Newsgroup:  news.php.net/php.pear.bugs
Subject:  

[PEAR-BUG] Bug #20383 [Com]: Files written outside INSTALL_ROOT install

NNTP-Posting-Host:  null

Edit report at https://pear.php.net/bugs/bug.php?id=20383&edit=1

 ID:               20383
 Comment by:       phpbug@monumentmail.com
 Reported By:      phpbug at monumentmail dot com
 Summary:          Files written outside INSTALL_ROOT install
 Status:           Open
 Type:             Bug
 Package:          PEAR
 Operating System: Linux
 Package Version:  Unknown
 PHP Version:      5.6.0
 Roadmap Versions: 
 New Comment:

No change an still bugged in PHP 5.6.5.


Previous Comments:
------------------------------------------------------------------------

[2014-09-01 18:39:31] phppearbug

And a second follow up.
I replaced the 'runtime' components in phar file with the contents of
the tar files which were included in the phar.
So, in effect, making an installer using the 1.9.5 version of PEAR, and
versions of Tar and friends which were in the phar, as noted in my
original report as a thing to try.

I still obviously used patch1.patch to get one of the 2 surplus
databases gone, but unfortunately, using 1.9.5 fixed nothing.
The other surplus database was still there in $HOME/php/

------------------------------------------------------------------------

[2014-09-01 18:29:35] phppearbug

As a follow up, I just noticed that patch2.patch now causes make
install-pear to install the windows bat files to bin, instead of the
*nix shell files.
So, patch2.patch should definitely not be used.

------------------------------------------------------------------------

[2014-09-01 17:05:30] phppearbug

Added #patch bug:20383;patch:patch2.patch;revision:1409587530;.

------------------------------------------------------------------------

[2014-09-01 17:05:02] phppearbug

Added #patch bug:20383;patch:patch1.patch;revision:1409587502;.

------------------------------------------------------------------------

[2014-09-01 17:02:17] phppearbug

Description:
------------
See the following 'standard' install sequence with an INSTALL_ROOT.
The result is 2 PEAR databases created where they should not have been.
One is outside the INSTALL_ROOT, on the location where it would have
been.
The other is in the root of INSTALL_ROOT itself.
This problem is also present in the 5.5.*, 5.4.* and 5.3.* branches.

Analysis of this is below the example.

test:~/php-5.6.0$ ./configure --prefix=$HOME/php
test:~/php-5.6.0$ make
test:~/php-5.6.0$ ls -l $HOME

total 4
drwxr-xr-x 17 test users 4096 Sep  1 08:00 php-5.6.0/

test:~/php-5.6.0$ make install INSTALL_ROOT=$HOME/staging
test:~/php-5.6.0$ ls -al $HOME

total 12
drwxr-xr-x  3 test users 4096 Sep  1 08:02 php/
drwxr-xr-x 17 test users 4096 Sep  1 08:00 php-5.6.0/
drwxr-xr-x  5 test users 4096 Sep  1 08:02 staging/

-- The php directory should not have been created here, as we installed
with INSTALL_ROOT.

test:~/php-5.6.0$ find $HOME/php

/home/test/php
/home/test/php/lib
/home/test/php/lib/php
/home/test/php/lib/php/.depdb
/home/test/php/lib/php/.filemap
/home/test/php/lib/php/.depdblock
/home/test/php/lib/php/.lock
/home/test/php/lib/php/.registry
/home/test/php/lib/php/.registry/.channel.__uri
/home/test/php/lib/php/.registry/.channel.pecl.php.net
/home/test/php/lib/php/.registry/.channel.doc.php.net
/home/test/php/lib/php/.channels
/home/test/php/lib/php/.channels/doc.php.net.reg
/home/test/php/lib/php/.channels/__uri.reg
/home/test/php/lib/php/.channels/pear.php.net.reg
/home/test/php/lib/php/.channels/.alias
/home/test/php/lib/php/.channels/.alias/phpdocs.txt
/home/test/php/lib/php/.channels/.alias/pear.txt
/home/test/php/lib/php/.channels/.alias/pecl.txt
/home/test/php/lib/php/.channels/pecl.php.net.reg

-- This is an empty PEAR database

test:~/php-5.6.0$ find $HOME/staging

/home/test/staging
/home/test/staging/.depdb
/home/test/staging/.filemap
/home/test/staging/.depdblock
/home/test/staging/.lock
/home/test/staging/.registry
/home/test/staging/.registry/.channel.__uri
/home/test/staging/.registry/.channel.pecl.php.net
/home/test/staging/.registry/.channel.doc.php.net
/home/test/staging/home
/home/test/staging/home/test
/home/test/staging/home/test/php
/home/test/staging/home/test/php/etc
/home/test/staging/home/test/php/etc/pear.conf
...
...
/home/test/staging/home/test/php/bin/php-cgi
/home/test/staging/home/test/php/bin/php
/home/test/staging/.channels
/home/test/staging/.channels/doc.php.net.reg
/home/test/staging/.channels/__uri.reg
/home/test/staging/.channels/pear.php.net.reg
/home/test/staging/.channels/.alias
/home/test/staging/.channels/.alias/phpdocs.txt
/home/test/staging/.channels/.alias/pear.txt
/home/test/staging/.channels/.alias/pecl.txt
/home/test/staging/.channels/pecl.php.net.reg

-- And a second empty PEAR database in the root of the staging
directory.
-- The correct PEAR database is at
'/home/test/staging/home/test/php/lib/php/'.
-- The sub install command 'make install-pear
INSTALL_ROOT=$HOME/staging' gives the same result.

I have tried to find out what caused this behavior and it stems from the
PEAR installation file
located at 'php-5.6.0/pear/install-pear-nozlib.phar'.
Trying to pinpoint it, it seems to always get back to some logic in
'PEAR/Registry.php' in this archive.

In normal operation (no INSTALL_ROOT), there are only 2 registry objects
made, with proper paths.

However, with the use of INSTALL_ROOT, the registry objects seem to be
recreated constantly, with
different paths to the php root, and by different objects in the PEAR
installation.
These recreations eventually lead to assertion of paths, usually by
locking or re-locking of the
registry databases, which then create the database if  it does not
exist.

I could trace the creation of the database in the root of INSTALL_ROOT
on line 208 in index.php:
  $reg = &new PEAR_Registry($options['packagingroot']);
I fixed this with:
  $reg = &new PEAR_Registry($options['packagingroot'] .
DIRECTORY_SEPARATOR . $config->get('php_dir'));

This seems to be ok, for as far as I can understand what is going on,
and it seems to fit the logic.
This fix is found in patch1.patch, but I must note that I have
absolutely no experience with the
inner working of the PEAR code, so I have no idea if this is indeed the
logic and proper fix.
I did add a small cosmetic patch to this patch too (see below).

For the other surplus database, created outside the INSTALL_ROOT all
together, I know that the fix I
have created is completely wrong (patch2.patch).
The recreation of the registry objects is all over the place, and as I
said, having no experience with
the inner workings of PEAR, I have no idea what is right and what is
not.

The patch I have created merely fixes the symptoms, mostly by just
disabling locking and some changes
to other places.
I think, or at least I deduced from the call stacks which get to the
lock, that the recreation of the
registry objects themselves are likely the real problem, but my attempts
to fix it like that all ave stranded
into nothingness.

A small snippet of code I used is the following:
print "---- setInstallDir() $pear_install_dir\n";
$trace = debug_backtrace();
for ($i = 0; $i < count($trace); $i++) print $trace[$i]["file"] . ":" .
$trace[$i]["function"] . " (" . $trace[$i]["line"] . ")\n";

I put this at various entries of functions to get the said call stacks,
especially at setInstallDir(),
the various _assert*Dir() and _lock().
The first line obviously changed to indicate the current function, and
the path of intrest (like
$this->install_dir in case of some of the asserts).
The difference between a make install without INSTALL_ROOT and with is
quite striking, especially with
regard to the calling of setInstallDir(), which is mainly (exclusively?)
called by the constructor.

One of the things I did notice was that the paths in the $config object
(in installer.php) seemingly gets
changed after the 1st iteration in the foreach loop.
The fix I applied is an extreme hack, I failed to track down why it
changed.

So, final words, I have no idea how to fix this properly, but I hope I
have given an adequate description
of the problem and did some proper analyzing of the root cause.
I'm of course more then happy to do some more digging if required, but
it probably is best if someone who
actually knows how PEAR is supposed to work can look at it, or at least
give some idea on how to proceed.

The small cosmetic thing:
[PEAR] Archive_Tar    - installed: 1.3.12
[PEAR] Console_Getopt - installed: 1.3.1
[PEAR] Structures_Graph- installed: 1.0.4
[PEAR] XML_Util       - installed: 1.2.3
[PEAR] PEAR           - installed: 1.9.5

The Structures_Graph is longer then the rest and touches the dash, so I
guess 2 spaces need to be added to the lines.
I fixed this in patch1.patch too, as stated above.

ps.
I have not tried it, and I have no idea if things actually work like
this, but it seems that the runtime PEAR
inside the phar archive itself is not the same version as the tarred one
which get installed.
If there is a bug in the runtime version, it likely is also in the 1.9.5
version? Or could it be fixed there?
Or is that tarred version not usable as a 'bootstrap' version as in the
phar?
(As I said, I really don't know how PEAR works, just guessing a bit
here.)

------------------------------------------------------------------------


-- 
Edit this bug report at https://pear.php.net/bugs/bug.php?id=20383&edit=1