php / php-src

The PHP Interpreter
https://www.php.net
Other
37.6k stars 7.7k forks source link

realpath() and SplFileInfo::getRealPath inside Phar #14481

Open murrant opened 1 month ago

murrant commented 1 month ago

Description

I'm trying to include packages in my phar but many of them use realpath to files inside the Phar which spits out false instead of a path; breaking things. If the behavior was to return the same path when the path starts with phar:// it would just work.

The following code:

make_phar.php

<?php
$phar = new Phar('test.phar');
$phar->addFile('test.php');
$phar->setDefaultStub('test.php');
$phar->stopBuffering();

test.php

<?php
var_dump(
    __FILE__,
    realpath(__FILE__), 
    (new SplFileInfo(__FILE__))->getRealPath(),
);

php test.php && php make_phar.php && php test.phar

Resulted in this output:

string(45) "/home/murrant/projects/realpath_test/test.php"
string(45) "/home/murrant/projects/realpath_test/test.php"
string(45) "/home/murrant/projects/realpath_test/test.php"
string(62) "phar:///home/murrant/projects/realpath_test/test.phar/test.php"
bool(false)
bool(false)

But I expected this output instead:

string(45) "/home/murrant/projects/realpath_test/test.php"
string(45) "/home/murrant/projects/realpath_test/test.php"
string(45) "/home/murrant/projects/realpath_test/test.php"
string(62) "phar:///home/murrant/projects/realpath_test/test.phar/test.php"
string(62) "phar:///home/murrant/projects/realpath_test/test.phar/test.php"
string(62) "phar:///home/murrant/projects/realpath_test/test.phar/test.php"

PHP Version

PHP 8.3.7

Operating System

No response

nielsdos commented 1 month ago

virtual_file_ex doesn't know about custom streams or phar, so it doesn't think the phar:// path is absolute. When it calls tsrm_realpath_r it will eventually perform a stat to /absolute/path/to/phar/phar:///absolute/path/to/phar/test.phar/test.php which obviously fails. We would need to strip the phar:// prefix or teach that callchain about the phar uri scheme... EDIT: changing this at the VCWD or virtual_file level seems like a bad idea given the other callers of e.g. VCWD_REALPATH... Not sure what the best solution would be here other than special-casing the userland realpath function.