3
* Gallery - a web based photo album viewer and editor
4
* Copyright (C) 2000-2007 Bharat Mediratta
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or (at
9
* your option) any later version.
11
* This program is distributed in the hope that it will be useful, but
12
* WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
22
* Test platform functionality.
23
* @package GalleryCore
25
* @author Bharat Mediratta <bharat@menalto.com>
26
* @version $Revision: 15728 $
28
class PlatformTest extends GalleryTestCase {
30
function PlatformTest($methodName) {
31
$this->GalleryTestCase($methodName);
38
$this->_platform =& $gallery->getPlatform();
39
$this->_sourceFile = dirname(__FILE__) . '/../data/test1.gif';
40
$this->_destFile = $gallery->getConfig('data.gallery.tmp') . 'test.dat';
44
$this->assert($this->_platform->copy($this->_sourceFile, $this->_destFile));
45
$this->assert($this->_platform->unlink($this->_destFile));
48
function testSymlink() {
49
if ($this->_platform->isSymlinkSupported()) {
50
$this->assert($this->_platform->symlink($this->_sourceFile, $this->_destFile));
51
$this->assert($this->_platform->unlink($this->_destFile));
55
function testMoveUploadedFile() {
56
/* XXX: How do we test this? We don't have an uploaded file :-( */
57
$this->assert(!$this->_platform->move_uploaded_file($this->_sourceFile, $this->_destFile));
60
function testFileExists() {
61
$this->assert($this->_platform->file_exists($this->_sourceFile));
62
$this->assert(!$this->_platform->file_exists($this->_destFile));
65
function testIsLink() {
66
$this->assert(!$this->_platform->is_link($this->_sourceFile));
69
function testIsDir() {
70
$this->assert($this->_platform->is_dir(dirname(__FILE__)));
71
$this->assert(!$this->_platform->is_dir(__FILE__));
74
function testIsFile() {
75
$this->assert($this->_platform->is_file(__FILE__));
76
$this->assert(!$this->_platform->is_file('bogus-file-name'));
79
function testIsWriteable() {
80
/* On Win32, all files are writeable so the next assertion isn't that useful! */
81
/* $this->assert(!$this->_platform->is_writeable(__FILE__)); */
83
$this->assert($this->_platform->copy($this->_sourceFile, $this->_destFile));
84
$this->assert($this->_platform->is_writeable($this->_destFile));
85
$this->assert($this->_platform->unlink($this->_destFile));
88
function testIsReadable() {
89
$this->assert($this->_platform->is_readable($this->_sourceFile));
92
function testIsUploadedFile() {
93
$this->assert(!$this->_platform->is_uploaded_file($this->_sourceFile));
96
function testIsExecutable() {
97
if (GalleryUtilities::isA($this->_platform, 'WinNtPlatform')) {
98
$this->assert($this->_platform->is_executable($this->_sourceFile));
100
$this->assert(!$this->_platform->is_executable($this->_sourceFile));
104
function testFilesize() {
105
$this->assertEquals(1083,
106
$this->_platform->filesize($this->_sourceFile));
109
function testFile() {
110
$lines = $this->_platform->file(__FILE__);
112
/* --> Target Line <-- */
113
$this->assertEquals("/* --> Target Line <-- */", trim($lines[__LINE__-2]));
116
function testFopen() {
117
$fd = $this->_platform->fopen($this->_sourceFile, 'r');
122
function testOpendir() {
123
$dir = $this->_platform->opendir(dirname(__FILE__));
125
$this->_platform->closedir($dir);
128
function testReaddir() {
129
$dir = $this->_platform->opendir(dirname(__FILE__));
131
while ($filename = $this->_platform->readdir($dir)) {
132
$files[$filename] = 1;
134
$this->_platform->closedir($dir);
136
$this->assertEquals(1, $files[basename(__FILE__)]);
139
function testRename() {
140
$this->assert($this->_platform->copy($this->_sourceFile, $this->_destFile));
141
$this->assert($this->_platform->rename($this->_destFile,
142
$this->_destFile . '-new'));
143
$this->assert($this->_platform->unlink($this->_destFile . '-new'));
146
function testStat() {
147
$this->assert($this->_platform->stat($this->_sourceFile));
150
function testUnlink() {
151
$this->assert($this->_platform->copy($this->_sourceFile, $this->_destFile));
152
$this->assert($this->_platform->unlink($this->_destFile));
155
function testRmdir() {
156
$this->assert($this->_platform->mkdir($this->_destFile));
157
$this->assert($this->_platform->mkdir($this->_destFile . '/1'));
159
/* XXX: this generates a PHP error that I can't seem to turn off. */
160
/* $this->assert(!$this->_platform->rmdir($this->_destFile)); */
162
$this->assert($this->_platform->rmdir($this->_destFile . '/1'));
163
$this->assert($this->_platform->rmdir($this->_destFile));
166
function testRecursiveRmdir() {
167
$this->assert($this->_platform->mkdir($this->_destFile));
168
$this->assert($this->_platform->mkdir($this->_destFile . '/1'));
169
$this->assert($this->_platform->mkdir($this->_destFile . '/1/2'));
170
$this->assert($this->_platform->mkdir($this->_destFile . '/1/2/3'));
171
$this->assert($this->_platform->recursiveRmdir($this->_destFile), 'remove');
174
function testMkdir() {
175
$this->assert($this->_platform->mkdir($this->_destFile), 'mkdir');
176
$this->assert($this->_platform->recursiveRmdir($this->_destFile));
179
function testIsLegalPathComponent() {
180
$this->assert($this->_platform->isLegalPathComponent('TheQuickBrownFox'));
181
$this->assert(!$this->_platform->isLegalPathComponent('The!QuickBrownFox'));
184
function testLegalizePathComponent() {
185
$this->assertEquals('The_Quick_',
186
$this->_platform->legalizePathComponent('The!Quick$'));
189
function testLegalizePathComponent2() {
190
$this->assertEquals('test_php',
191
$this->_platform->legalizePathComponent('test.php'));
194
function testLegalizePathComponent3() {
195
$this->assertEquals('test_php.jpg',
196
$this->_platform->legalizePathComponent('test.php.jpg'));
199
function testPathComponentLegalCharactersConserved() {
200
$this->assertEquals(true,
201
$this->_platform->isLegalPathComponent('TheQuickBrownFox'));
202
$this->assertEquals('TheQuickBrownFox',
203
$this->_platform->legalizePathComponent('TheQuickBrownFox'));
206
function testPathComponentIllegalCharactersToUnderscores() {
207
$this->assertEquals(false,
208
$this->_platform->isLegalPathComponent('The Quick!Brown#Fox'));
209
$this->assertEquals('The Quick_Brown#Fox',
210
$this->_platform->legalizePathComponent('The Quick!Brown#Fox'));
213
function testPathComponentDotInFileBaseToUnderscore() {
214
$this->assertEquals(false,
215
$this->_platform->isLegalPathComponent('test.php.jpg'));
216
$this->assertEquals('test_php.jpg',
217
$this->_platform->legalizePathComponent('test.php.jpg'));
220
function testPathComponentDotRecognizedExtensionConserved() {
221
$this->assertEquals(true,
222
$this->_platform->isLegalPathComponent('test.jpg'));
223
$this->assertEquals('test.jpg',
224
$this->_platform->legalizePathComponent('test.jpg'));
227
function testPathComponentDotUnrecognizedExtensionToUnderscore() {
228
$this->assertEquals(false,
229
$this->_platform->isLegalPathComponent('test.foo'));
230
$this->assertEquals('test_foo',
231
$this->_platform->legalizePathComponent('test.foo'));
234
function testPathComponentDotPhpExtensionToUnderscore() {
235
$this->assertEquals(false,
236
$this->_platform->isLegalPathComponent('test.php'));
237
$this->assertEquals('test_php',
238
$this->_platform->legalizePathComponent('test.php'));
241
function testPathComponentDotUnderscoreToUnderscoreUnderscore() {
242
$this->assertEquals(false,
243
$this->_platform->isLegalPathComponent('._test'));
244
$this->assertEquals('__test',
245
$this->_platform->legalizePathComponent('._test'));
249
* Make sure executing a bogus path fails.
251
* XXX: This is a pretty weak test. It's hard to improve it without actually shipping a
252
* known-good script though.
254
function testExec() {
255
$results = $this->_platform->exec(array(array('/bogus/path')));
256
$this->assertEquals(false, $results[0]);
260
* Make sure files are written with correct permissions by exec, copy, symlink,
261
* atomicWrite; test chmod.
263
function testPermissions() {
264
if (GalleryUtilities::isA($this->_platform, 'UnixPlatform')) {
265
if ($this->_markPluginParametersForCleanup('module', 'core')) {
268
$ret = GalleryCoreApi::setPluginParameter('module', 'core', 'permissions.file', '600');
270
return $this->failWithStatus($ret);
272
$this->_platform->resetPlatform();
273
$this->_permissionTest(0600, 1, array('copy', 'atomicWrite', 'symlink'));
275
$ret = GalleryCoreApi::setPluginParameter('module', 'core', 'permissions.file', '664');
277
return $this->failWithStatus($ret);
279
$this->_platform->resetPlatform();
280
$this->_permissionTest(0664, 2, array('copy', 'symlink', 'atomicWrite'));
282
$this->assert($this->_platform->copy($this->_sourceFile, $this->_destFile), 'copy');
283
$ret = GalleryCoreApi::setPluginParameter('module', 'core', 'permissions.file', '612');
285
return $this->failWithStatus($ret);
287
$this->_platform->resetPlatform();
288
$this->_permissionTest(0612, 3, array('chmod'));
290
$this->assert($this->_platform->mkdir($this->_destFile), 'mkdir');
291
$ret = GalleryCoreApi::setPluginParameter('module', 'core',
292
'permissions.directory', '751');
294
return $this->failWithStatus($ret);
296
$this->_platform->resetPlatform();
297
$this->_permissionTest(0751, 4, array('chmod'));
299
/* exec now uses a default umask of 022 -- exec'ers must chmod output files */
300
$this->_permissionTest(0644, 5, array('exec'));
302
$this->_platform->resetPlatform();
306
function _permissionTest($expectedPermissions, $testNumber, $tests) {
308
foreach ($tests as $test) {
312
$gallery->startRecordingDebugSnippet();
313
$results = $this->_platform->exec(
314
array(array('echo', 'test', '>', $this->_destFile)));
315
$debug = $gallery->stopRecordingDebugSnippet();
316
$this->assert($results[0], "exec $testNumber $debug");
317
$stat = $this->_platform->stat($this->_destFile);
321
$this->assert($this->_platform->copy($this->_sourceFile, $this->_destFile),
323
$stat = $this->_platform->stat($this->_destFile);
327
if (!$this->_platform->isSymlinkSupported()) {
328
$this->assert(false, 'symlink not supported');
331
$this->assert($this->_platform->symlink($this->_sourceFile, $this->_destFile),
332
"symlink $testNumber");
333
$stat = lstat($this->_destFile);
337
$this->assert($this->_platform->atomicWrite($this->_destFile, 'test'),
338
"atomicWrite $testNumber");
339
$stat = $this->_platform->stat($this->_destFile);
343
$this->assert($this->_platform->chmod($this->_destFile), "chmod $testNumber");
344
$this->_platform->clearstatcache(); /* is_dir call in chmod() cached old perm */
345
$stat = $this->_platform->stat($this->_destFile);
348
$this->assert(!empty($stat), "$test stat $testNumber $debug");
349
if ($test == 'symlink') {
350
/* On some systems symlinks always have 777 permissions */
351
$this->assert(($stat[2] & 0777) == $expectedPermissions ||
352
($stat[2] & 0777) == 0777,
353
"$test permissions $testNumber (" . decoct($expectedPermissions) .
354
' != ' . decoct($stat[2] & 0777) . ' or 777)');
356
$this->assertEquals(decoct($expectedPermissions), decoct($stat[2] & 0777),
357
"$test permissions $testNumber");
359
if ($testNumber == 4) {
360
$this->assert($this->_platform->rmdir($this->_destFile), "$test rmdir $testNumber");
362
$this->assert($this->_platform->unlink($this->_destFile),
363
"$test unlink $testNumber");
365
$this->_platform->clearstatcache();
369
function _setupChmodTest() {
370
$this->assert($this->_platform->mkdir($this->_destFile), 'mkdir');
371
$this->assert($this->_platform->mkdir($this->_destFile . '/1'), 'mkdir/1');
372
$this->assert($this->_platform->copy($this->_sourceFile, $this->_destFile . '/1/2'), 'cp');
373
$this->assert($this->_platform->mkdir($this->_destFile . '/1/3'), 'mkdir/1/3');
374
$this->assert($this->_platform->copy($this->_sourceFile, $this->_destFile . '/1/3/4'),
376
$this->assert($this->_platform->mkdir($this->_destFile . '/1/5'), 'mkdir/1/5');
378
$ret = $this->_markPluginParametersForCleanup('module', 'core');
382
$ret = GalleryCoreApi::setPluginParameter('module', 'core', 'permissions.directory', '734');
386
$ret = GalleryCoreApi::setPluginParameter('module', 'core', 'permissions.file', '652');
393
function testRecursiveChmod1() {
394
/* Set dir and file permissions by system prefs */
395
$ret = $this->_setupChmodTest();
397
return $this->failWithStatus($ret);
400
$this->_platform->resetPlatform();
401
$this->assert($this->_platform->recursiveChmod($this->_destFile), 'set perms');
402
$this->_platform->clearstatcache();
403
$expected = GalleryUtilities::isA($this->_platform, 'WinNtPlatform') ? '777' : '734';
404
$expected2 = GalleryUtilities::isA($this->_platform, 'WinNtPlatform') ? '777' : '652';
405
$expected3 = GalleryUtilities::isA($this->_platform, 'WinNtPlatform') ? '666' : '652';
407
$stat = $this->_platform->stat($this->_destFile);
408
$this->assertEquals($expected, decoct($stat[2] & 0777), 'perm0');
409
$stat = $this->_platform->stat($this->_destFile . '/1');
410
$this->assertEquals($expected, decoct($stat[2] & 0777), 'perm1');
411
$stat = $this->_platform->stat($this->_destFile . '/1/2');
412
$this->assertEquals($expected3, decoct($stat[2] & 0777), 'perm2');
413
$stat = $this->_platform->stat($this->_destFile . '/1/3');
414
$this->assertEquals($expected, decoct($stat[2] & 0777), 'perm3');
415
$stat = $this->_platform->stat($this->_destFile . '/1/3/4');
416
$this->assertEquals($expected3, decoct($stat[2] & 0777), 'perm4');
417
$stat = $this->_platform->stat($this->_destFile . '/1/5');
418
$this->assertEquals($expected, decoct($stat[2] & 0777), 'perm5');
420
$this->assert($this->_platform->recursiveRmdir($this->_destFile), 'remove');
421
$this->_platform->resetPlatform();
424
function testRecursiveChmod2() {
425
/* Set given dir permission, don't change file permissions */
426
$ret = $this->_setupChmodTest();
428
return $this->failWithStatus($ret);
431
$fileStat = $this->_platform->stat($this->_destFile . '/1/2');
432
$fileStat = decoct($fileStat[2]);
433
$this->_platform->resetPlatform();
435
$this->assert($this->_platform->recursiveChmod($this->_destFile, 0711, -1), 'set perms');
436
$this->_platform->clearstatcache();
437
$expected = GalleryUtilities::isA($this->_platform, 'WinNtPlatform') ? '777' : '711';
439
$stat = $this->_platform->stat($this->_destFile);
440
$this->assertEquals($expected, decoct($stat[2] & 0777), 'perm0');
441
$stat = $this->_platform->stat($this->_destFile . '/1');
442
$this->assertEquals($expected, decoct($stat[2] & 0777), 'perm1');
443
$stat = $this->_platform->stat($this->_destFile . '/1/2');
444
$this->assertEquals($fileStat, decoct($stat[2]), 'file2 should be unchanged');
445
$stat = $this->_platform->stat($this->_destFile . '/1/3');
446
$this->assertEquals($expected, decoct($stat[2] & 0777), 'perm3');
447
$stat = $this->_platform->stat($this->_destFile . '/1/3/4');
448
$this->assertEquals($fileStat, decoct($stat[2]), 'file4 should be unchanged');
449
$stat = $this->_platform->stat($this->_destFile . '/1/5');
450
$this->assertEquals($expected, decoct($stat[2] & 0777), 'perm5');
452
$this->assert($this->_platform->recursiveRmdir($this->_destFile), 'remove');
453
$this->_platform->resetPlatform();
456
function testRecursiveChmod3() {
457
/* Set given file permission, don't change dir permissions */
458
$ret = $this->_setupChmodTest();
460
return $this->failWithStatus($ret);
463
$dirStat = $this->_platform->stat($this->_destFile . '/1');
464
$dirStat = decoct($dirStat[2]);
465
$this->_platform->resetPlatform();
467
$this->assert($this->_platform->recursiveChmod($this->_destFile, -1, 0640), 'set perms');
468
$this->_platform->clearstatcache();
469
$expected = GalleryUtilities::isA($this->_platform, 'WinNtPlatform') ? '777' : '640';
470
$expected2 = GalleryUtilities::isA($this->_platform, 'WinNtPlatform') ? '666' : '640';
472
$stat = $this->_platform->stat($this->_destFile);
473
$this->assertEquals($dirStat, decoct($stat[2]), 'dir0 should be unchanged');
474
$stat = $this->_platform->stat($this->_destFile . '/1');
475
$this->assertEquals($dirStat, decoct($stat[2]), 'dir1 should be unchanged');
476
$stat = $this->_platform->stat($this->_destFile . '/1/2');
477
$this->assertEquals($expected2, decoct($stat[2] & 0777), 'perm2');
478
$stat = $this->_platform->stat($this->_destFile . '/1/3');
479
$this->assertEquals($dirStat, decoct($stat[2]), 'dir3 should be unchanged');
480
$stat = $this->_platform->stat($this->_destFile . '/1/3/4');
481
$this->assertEquals($expected2, decoct($stat[2] & 0777), 'perm4');
482
$stat = $this->_platform->stat($this->_destFile . '/1/5');
483
$this->assertEquals($dirStat, decoct($stat[2]), 'dir5 should be unchanged');
485
$this->assert($this->_platform->recursiveRmdir($this->_destFile), 'remove');
486
$this->_platform->resetPlatform();
489
function testGetDirectorySeparator() {
491
$realSeparator = $file[strlen(dirname(__FILE__))];
492
$this->assertEquals($realSeparator, $this->_platform->getDirectorySeparator());
495
function testGetLineEnding() {
496
if (GalleryUtilities::isA($this->_platform, 'UnixPlatform')) {
497
$realLineEnding = "\n";
498
} else if (GalleryUtilities::isA($this->_platform, 'WinNtPlatform')) {
499
$realLineEnding = "\r\n";
502
$this->assertEquals($realLineEnding, $this->_platform->getLineEnding(),
503
"Line Endings Don't Match");
506
function testIsRestrictedByOpenBaseDir() {
508
$isWin = GalleryUtilities::isA($this->_platform, 'WinNtPlatform');
510
$this->assert(!$this->_platform->isRestrictedByOpenBaseDir(__FILE__), 'this file');
512
$gallery->_phpVm = new PlatformTestPhpVm(dirname(__FILE__), $this);
513
$this->assert(!$this->_platform->isRestrictedByOpenBaseDir(__FILE__), 'simple case');
515
/* Bad paths are still checked even though no realpath */
517
!$this->_platform->isRestrictedByOpenBaseDir(dirname(__FILE__) . '/bogus/path'),
518
'bogus path "inside" valid dir');
520
$this->_platform->isRestrictedByOpenBaseDir(dirname(__FILE__) . '/../bogus/path'),
521
'bogus path using .. to get outside valid dir');
522
$gallery->_phpVm = new PlatformTestPhpVm('', $this);
523
$this->assert(!$this->_platform->isRestrictedByOpenBaseDir('/bogus/path'),
524
'bogus path with no restriction');
526
/* Open_basedir with multiple entries */
527
$platform = $isWin ? new PlatformTestOpenBaseDirWinNtPlatform()
528
: new PlatformTestOpenBaseDirUnixPlatform();
529
$platform->setRealpathData(array('C:\\Test' => 'C:\\Test',
530
'C:\\Test\\file' => 'C:\\Test\\file',
531
'D:\\Fun\\' => 'D:\\Fun',
532
'D:\\Fun\\file' => 'D:\\Fun\\file',
533
'/test' => '/test', '/fun/' => '/fun',
534
'/test/file' => '/test/file', '/fun/file' => '/fun/file',
535
'c:\\TEST\\file' => 'C:\\Test\\file',
536
'/TEST/file' => '/TEST/file'));
539
new PlatformTestPhpVm($isWin ? 'C:\\Test;D:\\Fun\\' : '/test:/fun/', $this);
541
!$platform->isRestrictedByOpenBaseDir($isWin ? 'C:\\Test\\file' : '/test/file'),
544
!$platform->isRestrictedByOpenBaseDir($isWin ? 'D:\\Fun\\file' : '/fun/file'),
546
$this->assertEquals(!$isWin,
547
$platform->isRestrictedByOpenBaseDir($isWin ? 'c:\\TEST\\file' : '/TEST/file'),
548
'unix case sensitive, windows not');
550
/* Symlinks are resolved in both given path and open_basedir list */
552
$platform->setRealpathData(array('/test/real' => '/test/real',
553
'/test/real/file' => '/test/real/file',
554
'/test/link' => '/test/real',
555
'/test/link/file' => '/test/real/file',
556
'/test/real/linktoetc/passwd' => '/etc/passwd',
557
'/test/link/linktoetc/passwd' => '/etc/passwd'));
559
$gallery->_phpVm = new PlatformTestPhpVm('/test/real', $this);
560
$this->assert(!$platform->isRestrictedByOpenBaseDir('/test/link/file'),
561
'path with symlink, open_basedir has realpath');
562
$this->assert($platform->isRestrictedByOpenBaseDir('/test/real/linktoetc/passwd'),
563
'symlink to outside, open_basedir has realpath');
564
$this->assert($platform->isRestrictedByOpenBaseDir('/test/link/bogus/path'),
565
'invalid path with symlink, open_basedir has realpath');
567
$gallery->_phpVm = new PlatformTestPhpVm('/test/link', $this);
568
$this->assert(!$platform->isRestrictedByOpenBaseDir('/test/real/file'),
569
'realpath given, open_basedir has symlink');
570
$this->assert($platform->isRestrictedByOpenBaseDir('/test/link/linktoetc/passwd'),
571
'symlink to outside, open_basedir has symlink');
572
$this->assert($platform->isRestrictedByOpenBaseDir('/test/link/bogus/path'),
573
'invalid path with symlink, open_basedir has symlink');
574
$this->assert(!$platform->isRestrictedByOpenBaseDir('/test/real/bogus/path'),
575
'invalid path, open_basedir has symlink');
578
/* Open_basedir entry can be a prefix and not a real dir */
579
$platform->setRealpathData(array('/tes' => false, '/test' => '/test',
580
'/testfile' => '/testfile',
581
'/test/file' => '/test/file',
582
'/toast/file' => '/toast/file',
583
'/link/file' => '/test/file'));
585
$gallery->_phpVm = new PlatformTestPhpVm('/tes', $this);
586
$this->assert(!$platform->isRestrictedByOpenBaseDir('/testfile'), 'file with prefix');
587
$this->assert(!$platform->isRestrictedByOpenBaseDir('/test/file'), 'dir with prefix');
588
$this->assert(!$platform->isRestrictedByOpenBaseDir('/tes/bad/path'),
589
'given path can be invalid and match a prefix');
590
/* though it would be restricted if /tes was a real dir? odd.. */
591
$this->assert($platform->isRestrictedByOpenBaseDir('/toast/file'), 'not match prefix');
593
/* Symlink expansion with prefix (realpath of given path must match prefix) */
594
$this->assert(!$platform->isRestrictedByOpenBaseDir('/link/file'),
595
'link, realpath has prefix');
597
$platform->setRealpathData(array('/lin' => false, '/link' => '/test',
598
'/linnen' => '/linnen',
599
'/linkfile' => '/testfile',
600
'/link/file' => '/test/file',
601
'/lonk/file' => '/lonk/file',
602
'/link/fu' => false, '/link/fun' => '/test/fun',
603
'/test/fun' => '/test/fun'));
604
$gallery->_phpVm = new PlatformTestPhpVm('/lin', $this);
605
$this->assert(!$platform->isRestrictedByOpenBaseDir('/linnen'), 'nonlink with prefix');
606
$this->assert($platform->isRestrictedByOpenBaseDir('/linkfile'), 'link with prefix');
607
$this->assert($platform->isRestrictedByOpenBaseDir('/link/file'), 'dir with prefix');
608
$this->assert($platform->isRestrictedByOpenBaseDir('/lonk/file'), 'not match prefix');
610
$gallery->_phpVm = new PlatformTestPhpVm('/link/fu', $this);
611
$this->assert($platform->isRestrictedByOpenBaseDir('/test/fun'),
612
'realpath given, open_basedir has prefix with link parent');
613
$this->assert($platform->isRestrictedByOpenBaseDir('/link/fun'),
614
'valid link path given, open_basedir has prefix with link parent');
615
$this->assert(!$platform->isRestrictedByOpenBaseDir('/link/fubar'),
616
'invalid link path given, open_basedir has prefix with link parent');
619
/* Open_basedir with . */
620
$gallery->_phpVm = new PlatformTestPhpVm('.', $this);
621
$this->assert(!$this->_platform->isRestrictedByOpenBaseDir(
622
dirname(__FILE__) . '/../../../../lib/tools/phpunit/index.php'), 'dot basedir');
624
/* Open_basedir with trailing slash */
625
$s = $this->_platform->getDirectorySeparator();
626
$platform->setRealpathData(array("${s}test${s}" => "${s}test",
627
"${s}testing" => "${s}testing"));
628
$gallery->_phpVm = new PlatformTestPhpVm("${s}test${s}", $this);
629
$this->assert(!$platform->isRestrictedByOpenBaseDir("${s}test"), 'no trailing slash');
630
$this->assert($platform->isRestrictedByOpenBaseDir("${s}testing"),
631
'should not match basedir with trailing slash');
633
/* Invalid paths (realpath returns false, our code does relative path and .. handling) */
634
$platform->setRealpathData(array("${s}test" => "${s}test"));
635
$gallery->_phpVm = new PlatformTestPhpVm("${s}test", $this);
636
$this->assert(!$platform->isRestrictedByOpenBaseDir("${s}test${s}bogus"),
638
$this->assert(!$platform->isRestrictedByOpenBaseDir("${s}test${s}bogus${s}..${s}path"),
640
$this->assert($platform->isRestrictedByOpenBaseDir("${s}test${s}bogus${s}..${s}..${s}path"),
642
$this->assert($platform->isRestrictedByOpenBaseDir("${s}test${s}.."),
644
$this->assert(!$platform->isRestrictedByOpenBaseDir("${s}.${s}test${s}bogus"),
645
'dot in valid bogus path');
646
$this->assert(!$platform->isRestrictedByOpenBaseDir("${s}.${s}test${s}.${s}bogus"),
647
'two dots in valid bogus path');
648
$platform->setCwd("${s}test");
649
$this->assert(!$platform->isRestrictedByOpenBaseDir('bogus'),
650
'valid relative path');
651
$this->assert($platform->isRestrictedByOpenBaseDir("..${s}bogus"),
652
'invalid relative path');
653
$this->assert(!$platform->isRestrictedByOpenBaseDir("bogus${s}path${s}..${s}..${s}test"),
654
'valid relative path with two dotdots');
657
function testIsRestrictedByOpenBaseDirForMatchAllOpenBaseDir() {
660
$gallery->_phpVm = new PlatformTestPhpVm('/', $this);
661
$platform = new PlatformTestOpenBaseDirUnixPlatform();
662
$platform->setRealpathData(array('/test/file' => '/test/file',
664
$this->assert(!$platform->isRestrictedByOpenBaseDir('/'), '/ should be allowed');
665
$this->assert(!$platform->isRestrictedByOpenBaseDir('/test/file'),
666
'/test/file should be allowed');
670
* Try opening a socket to the current web server.
672
function testFsockopen() {
673
$fd = $this->_platform->fsockopen($_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'],
674
$errno, $errstr, 30);
675
$this->assert($fd, 'File descriptor should not be null/false');
676
@$this->_platform->fclose($fd);
680
* Try opening a socket to a bogus web server.
682
function testFsockopenBadHost() {
683
/* We know this is going to bomb so unset PHPunit's error handler */
684
restore_error_handler();
686
$fd = @$this->_platform->fsockopen('www.BOGUSBOGUSBOGUSBOGUS.com', $_SERVER['SERVER_PORT'],
687
$errno, $errstr, 30);
688
$this->assertEquals(false, $fd);
692
* Verify that we can write a few bytes to a file.
694
function testOpenWriteAndClose() {
695
$fd = $this->_platform->fopen($this->_destFile, 'wb');
696
$this->assert($fd, 'File descriptor should not be null');
698
$buf = 'this is a test';
699
$bytesWritten = $this->_platform->fwrite($fd, $buf, strlen($buf));
700
$this->assertEquals(strlen($buf), $bytesWritten);
702
$this->assert($this->_platform->fclose($fd), 'fclose');
703
$this->assert($this->_platform->unlink($this->_destFile), 'unlink');
706
function testOpenAndReadTillEof() {
707
$fd = $this->_platform->fopen($this->_sourceFile, 'rb');
708
$this->assert($fd, 'File descriptor should not be null');
711
while (!$this->_platform->feof($fd)) {
712
$buf .= $this->_platform->fread($fd, 512);
715
$this->assert(1083, strlen($buf));
716
$this->assert($this->_platform->fclose($fd));
719
function testOpenMissingFile() {
720
/* We know this is going to bomb so unset PHPunit's error handler */
721
restore_error_handler();
723
/* And suppress warnings when we call fopen */
724
$fd = @$this->_platform->fopen(sprintf('%s_BOGUS_BOGUS', __FILE__), 'rb');
725
$this->assertEquals(false, $fd);
728
function testAtomicWrite() {
730
* We should test if our operations are really concurrent-safe, but we cannot do that
731
* without having multiple processes accessing the same file, which is not possible in our
732
* test-framework (yet)
734
$testData1 = "this is a test\nmultiline\ntest";
735
$this->assert($this->_platform->atomicWrite($this->_destFile, $testData1, 'wb'),
737
$output = implode('', $this->_platform->file($this->_destFile));
738
$this->assertEquals($testData1, $output);
740
/* Now write another text to the same file and see if it's ok */
741
$testData2 = "this is a test\nmultiline\ntest\nmore\ntext";
742
$this->assert($this->_platform->atomicWrite($this->_destFile, $testData2, 'wb'),
744
$output = implode('', $this->_platform->file($this->_destFile));
745
$this->assertEquals($testData2, $output);
746
$this->assert($this->_platform->unlink($this->_destFile), 'unlink');
749
function testSplitPath() {
750
$this->assertEquals(array('dir', 'path', 'file.txt'),
751
$this->_platform->splitPath('dir/path/file.txt'), 'relative');
752
if (GalleryUtilities::isA($this->_platform, 'WinNtPlatform')) {
753
$this->assertEquals(array('c:\\', 'dir', 'path', 'file.txt'),
754
$this->_platform->splitPath('c:\dir\path\file.txt'), 'absolute');
755
$this->assertEquals(array('D:\\', 'path', 'file.txt'),
756
$this->_platform->splitPath('D:\path/file.txt'), 'absolute2');
757
$this->assertEquals(array('\\', 'test'),
758
$this->_platform->splitPath('\test'), 'absolute3');
760
$this->assertEquals(array('/', 'dir', 'path', 'file.txt'),
761
$this->_platform->splitPath('/dir/path/file.txt'), 'absolute');
765
function testChdir() {
767
$tmpdir = $gallery->getConfig('data.gallery.tmp');
768
$oldCwd = $this->_platform->getcwd();
769
$this->assert($oldCwd);
771
/* Change working directory to g2data/tmp */
772
$this->assert($this->_platform->chdir($tmpdir));
773
$newCwd = $this->_platform->getcwd();
774
$this->assertEquals(realpath($tmpdir), $newCwd);
776
/* Go back to original directory */
777
$this->_platform->chdir($oldCwd);
780
function testStrftime() {
781
$this->assertEquals('2005 03', $this->_platform->strftime('%Y %m', 1110101111));
782
/* For windows we replace %e with %d and convert leading zeros to spaces */
783
$this->assertEquals( ' 6 11', $this->_platform->strftime('%e %S', 1110101111));
785
/* Verify UTF-8 text in format string is not mangled (only % tokens convert to UTF-8) */
786
$this->assertEquals("\xd0\x9d\xd0\xb5 2005 \xd0\xbd %\n03",
787
$this->_platform->strftime("\xd0\x9d\xd0\xb5 %Y \xd0\xbd %%\n%m", 1110101111));
789
/* How to test that strftime output is converted to UTF-8? */
792
function testFileGetAndPutContents() {
793
$fileContents = $this->_platform->file_get_contents($this->_sourceFile);
794
$this->assert(is_string($fileContents), 'contents not a string');
795
$this->assert(false !== strpos($fileContents, 'GIF89'), 'invalid contents');
796
$this->assert(1083, strlen($fileContents));
798
$success = $this->_platform->file_put_contents($this->_destFile, $fileContents);
799
$this->assert($success, 'file_put_contents error');
800
$this->assertEquals(1083, $this->_platform->filesize($this->_destFile));
801
$this->assert($this->_platform->unlink($this->_destFile), 'unlink');
804
function testMailUsesUnixLineEndings() {
807
$ret = $this->_markPluginParametersForCleanup('module', 'core');
809
return $this->failWithStatus($ret);
811
$ret = GalleryCoreApi::setPluginParameter('module', 'core', 'smtp.host', null);
813
return $this->failWithStatus($ret);
816
$gallery->_phpVm = new PlatformTestPhpVm(dirname(__FILE__), $this);
817
$platform = new UnixPlatform();
818
$result = $platform->mail("foo@example.com", "subject",
819
"body line1\nline2\r\nline3\r\n",
820
"header line1\nline2\r\nline3\r\n");
821
$this->assert($result);
822
$this->assertEquals("body line1\nline2\nline3\n", $this->_mail['body']);
823
$this->assertEquals("header line1\nline2\nline3\n", $this->_mail['headers']);
827
class PlatformTestPhpVm extends GalleryPhpVm {
829
function PlatformTestPhpVm($iniVal, &$test) {
830
$this->_iniVal = $iniVal;
831
$this->_test =& $test;
834
function ini_get($varname) {
835
if ($varname == 'open_basedir') {
836
return $this->_iniVal;
838
return parent::ini_get($varname);
841
function mail($to, $subject, $body, $additionalHeaders=null, $additionalParameters=null) {
842
$this->_test->_mail = array('to' => $to,
845
'headers' => $additionalHeaders,
846
'params' => $additionalParameters);
851
GalleryCoreApi::requireOnce('modules/core/classes/GalleryPlatform/UnixPlatform.class');
852
class PlatformTestOpenBaseDirUnixPlatform extends UnixPlatform {
854
function setRealpathData($realpathData) {
855
$this->_realpathData = $realpathData;
858
function setCwd($path) {
862
function realpath($path) {
863
return isset($this->_realpathData[$path]) ? $this->_realpathData[$path] : false;
867
return isset($this->_cwd) ? $this->_cwd : parent::getcwd();
870
function getDirectorySeparator() {
875
GalleryCoreApi::requireOnce('modules/core/classes/GalleryPlatform/WinNtPlatform.class');
876
class PlatformTestOpenBaseDirWinNtPlatform extends WinNtPlatform {
878
function setRealpathData($realpathData) {
879
$this->_realpathData = $realpathData;
882
function setCwd($path) {
886
function realpath($path) {
887
return isset($this->_realpathData[$path]) ? $this->_realpathData[$path] : false;
891
return isset($this->_cwd) ? $this->_cwd : parent::getcwd();
894
function getDirectorySeparator() {