1--TEST--
2Bug #61367: open_basedir bypass in libxml RSHUTDOWN: read test
3--SKIPIF--
4<?php
5if(!extension_loaded('dom')) echo 'skip dom extension not available';
6if (LIBXML_VERSION < 20912) die('skip For libxml2 >= 2.9.12 only');
7?>
8--INI--
9open_basedir=.
10--FILE--
11<?php
12/*
13 * Note: Using error_reporting=E_ALL & ~E_NOTICE to suppress "Trying to get property of non-object" notices.
14 */
15class StreamExploiter {
16    public function stream_close (  ) {
17        $doc = new DOMDocument;
18        $doc->resolveExternals = true;
19        $doc->substituteEntities = true;
20        $dir = htmlspecialchars(dirname(getcwd()));
21        $dir = str_replace('\\', '/', $dir); // fix for windows
22        $doc->loadXML( <<<XML
23<!DOCTYPE doc [
24    <!ENTITY file SYSTEM "file:///$dir/bad">
25]>
26<doc>&file;</doc>
27XML
28        );
29        print $doc->documentElement->firstChild->nodeValue;
30    }
31
32    public function stream_open (  $path ,  $mode ,  $options ,  &$opened_path ) {
33        return true;
34    }
35}
36
37var_dump(mkdir('test_bug_61367-read'));
38var_dump(mkdir('test_bug_61367-read/base'));
39var_dump(file_put_contents('test_bug_61367-read/bad', 'blah'));
40var_dump(chdir('test_bug_61367-read/base'));
41
42stream_wrapper_register( 'exploit', 'StreamExploiter' );
43$s = fopen( 'exploit://', 'r' );
44
45?>
46--CLEAN--
47<?php
48unlink('test_bug_61367-read/bad');
49rmdir('test_bug_61367-read/base');
50rmdir('test_bug_61367-read');
51?>
52--EXPECTF--
53bool(true)
54bool(true)
55int(4)
56bool(true)
57
58Warning: DOMDocument::loadXML(): I/O warning : failed to load external entity "file:///%s/test_bug_61367-read/bad" in %s on line %d
59
60Notice: Trying to get property 'nodeValue' of non-object in %s on line %d
61