Security update for Core, with self-updated composer
[yaffs-website] / web / core / tests / Drupal / Tests / Core / DrupalKernel / DrupalKernelTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\DrupalKernel {
4
5   use Drupal\Core\DrupalKernel;
6   use Drupal\Tests\UnitTestCase;
7   use org\bovigo\vfs\vfsStream;
8   use Symfony\Component\ClassLoader\ApcClassLoader;
9   use Symfony\Component\HttpFoundation\Request;
10
11   /**
12    * @coversDefaultClass \Drupal\Core\DrupalKernel
13    * @group DrupalKernel
14    */
15   class DrupalKernelTest extends UnitTestCase {
16
17     /**
18      * Tests hostname validation with settings.
19      *
20      * @covers ::setupTrustedHosts
21      * @dataProvider providerTestTrustedHosts
22      */
23     public function testTrustedHosts($host, $server_name, $message, $expected = FALSE) {
24       $request = new Request();
25
26       $trusted_host_patterns = [
27         '^example\.com$',
28         '^.+\.example\.com$',
29         '^example\.org',
30         '^.+\.example\.org',
31       ];
32
33       if (!empty($host)) {
34         $request->headers->set('HOST', $host);
35       }
36
37       $request->server->set('SERVER_NAME', $server_name);
38
39       $method = new \ReflectionMethod('Drupal\Core\DrupalKernel', 'setupTrustedHosts');
40       $method->setAccessible(TRUE);
41       $valid_host = $method->invoke(NULL, $request, $trusted_host_patterns);
42
43       $this->assertSame($expected, $valid_host, $message);
44
45       // Reset the trusted hosts because it is statically stored on the request.
46       $method->invoke(NULL, $request, []);
47       // Reset the request factory because it is statically stored on the request.
48       Request::setFactory(NULL);
49     }
50
51     /**
52      * Tests the reregistration of autoloaders if APCu available.
53      *
54      * This test runs in a separate process since it registers class loaders and
55      * results in statics being set.
56      *
57      * @runInSeparateProcess
58      * @preserveGlobalState disabled
59      * @requires function apcu_fetch
60      * @covers ::initializeSettings
61      */
62     public function testInitializeSettings() {
63       $request = new Request();
64       $classloader = new fakeAutoloader();
65
66       // Create a kernel suitable for testing.
67       $kernel = $this->getMockBuilder(DrupalKernel::class)
68         ->disableOriginalConstructor()
69         ->setMethods(['do_not_mock_any_methods'])
70         ->getMock();
71       $classloader_property = new \ReflectionProperty($kernel, 'classLoader');
72       $classloader_property->setAccessible(TRUE);
73       $classloader_property->setValue($kernel, $classloader);
74       $method = new \ReflectionMethod($kernel, 'initializeSettings');
75       $method->setAccessible(TRUE);
76
77       // Prepend another autoloader to simulate Drush's autoloader.
78       $fake_drush_autoloader = function () {
79         return NULL;
80       };
81       spl_autoload_register($fake_drush_autoloader, TRUE, TRUE);
82
83       // Before calling DrupalKernel::initializeSettings() the first autoloader
84       // is the fake Drush autoloader.
85       $this->assertSame($fake_drush_autoloader, spl_autoload_functions()[0]);
86
87       // Call DrupalKernel::initializeSettings() to simulate part of a Drupal
88       // bootstrap. During the include of autoload.php Composer would prepend
89       // Drupal's autoloader and then this method should not result in Drush's
90       // autoloader becoming the first autoloader even if it swaps out
91       // Composer's autoloader for an optimised one.
92       $method->invoke($kernel, $request);
93
94       $autoloaders = spl_autoload_functions();
95       // The first autoloader should be the APCu based autoloader.
96       $this->assertInstanceOf(ApcClassLoader::class, $autoloaders[0][0]);
97       // The second autoloader should be the original autoloader the kernel was
98       // constructed with.
99       $this->assertSame($classloader, $autoloaders[1][0]);
100       // The third autoloader should be Drush's autoloader.
101       $this->assertSame($fake_drush_autoloader, $autoloaders[2]);
102
103       // Reset the request factory because it is statically stored on the
104       // request.
105       Request::setFactory(NULL);
106     }
107
108     /**
109      * Provides test data for testTrustedHosts().
110      */
111     public function providerTestTrustedHosts() {
112       $data = [];
113
114       // Tests canonical URL.
115       $data[] = [
116         'www.example.com',
117         'www.example.com',
118         'canonical URL is trusted',
119         TRUE
120       ];
121
122       // Tests missing hostname for HTTP/1.0 compatibility where the Host
123       // header is optional.
124       $data[] = [NULL, 'www.example.com', 'empty Host is valid', TRUE];
125
126       // Tests the additional patterns from the settings.
127       $data[] = [
128         'example.com',
129         'www.example.com',
130         'host from settings is trusted',
131         TRUE
132       ];
133       $data[] = [
134         'subdomain.example.com',
135         'www.example.com',
136         'host from settings is trusted',
137         TRUE
138       ];
139       $data[] = [
140         'www.example.org',
141         'www.example.com',
142         'host from settings is trusted',
143         TRUE
144       ];
145       $data[] = [
146         'example.org',
147         'www.example.com',
148         'host from settings is trusted',
149         TRUE
150       ];
151
152       // Tests mismatch.
153       $data[] = [
154         'www.blackhat.com',
155         'www.example.com',
156         'unspecified host is untrusted',
157         FALSE
158       ];
159
160       return $data;
161     }
162
163     /**
164      * Tests site path finding.
165      *
166      * This test is run in a separate process since it defines DRUPAL_ROOT. This
167      * stops any possible pollution of other tests.
168      *
169      * @covers ::findSitePath
170      * @runInSeparateProcess
171      */
172     public function testFindSitePath() {
173       $vfs_root = vfsStream::setup('drupal_root');
174       $sites_php = <<<'EOD'
175 <?php
176 $sites['8888.www.example.org'] = 'example';
177 EOD;
178
179       // Create the expected directory structure.
180       vfsStream::create([
181         'sites' => [
182           'sites.php' => $sites_php,
183           'example' => [
184             'settings.php' => 'test',
185           ],
186         ],
187       ]);
188
189       $request = new Request();
190       $request->server->set('SERVER_NAME', 'www.example.org');
191       $request->server->set('SERVER_PORT', '8888');
192       $request->server->set('SCRIPT_NAME', '/index.php');
193       $this->assertEquals('sites/example', DrupalKernel::findSitePath($request, TRUE, $vfs_root->url('drupal_root')));
194       $this->assertEquals('sites/example', DrupalKernel::findSitePath($request, FALSE, $vfs_root->url('drupal_root')));
195     }
196
197   }
198
199   /**
200    * A fake autoloader for testing
201    */
202   class fakeAutoloader {
203
204     /**
205      * Registers this instance as an autoloader.
206      *
207      * @param bool $prepend
208      *   Whether to prepend the autoloader or not
209      */
210     public function register($prepend = FALSE) {
211       spl_autoload_register([$this, 'loadClass'], TRUE, $prepend);
212     }
213
214     /**
215      * Unregisters this instance as an autoloader.
216      */
217     public function unregister() {
218       spl_autoload_unregister([$this, 'loadClass']);
219     }
220
221     /**
222      * Loads the given class or interface.
223      *
224      * @return null
225      *   This class never loads.
226      */
227     public function loadClass() {
228       return NULL;
229     }
230
231     /**
232      * Finds a file by class name while caching lookups to APC.
233      *
234      * @return null
235      *   This class never finds.
236      */
237     public function findFile() {
238       return NULL;
239     }
240
241   }
242 }
243
244
245 namespace {
246
247   if (!function_exists('drupal_valid_test_ua')) {
248     function drupal_valid_test_ua($new_prefix = NULL) {
249       return FALSE;
250     }
251   }
252 }