Skip to content

Commit

Permalink
fixed throwing errors in exists-check functions (#54) [Closes #52]
Browse files Browse the repository at this point in the history
Suppresses warning triggered by `stat`/`lstat` when file does not exit.

By injecting another error handler which resets error reporting the
suppressed warning gets caught and does not appear in error logs.

As certain testing frameworks establish error handlers to pick up
on suppressed errors, exceptions and warnings, the warning generated
by `stat`/`lstat` when provided an unknown path is recorded.
  • Loading branch information
oruborus authored and dg committed May 16, 2024
1 parent ed47c5f commit 91770cc
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/NativeWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,19 @@ public function unlink(string $path): bool

public function url_stat(string $path, int $flags)
{
if ($flags & STREAM_URL_STAT_QUIET) {
set_error_handler(static fn(): bool => true);
}
try {
$func = $flags & STREAM_URL_STAT_LINK ? 'lstat' : 'stat';
return $flags & STREAM_URL_STAT_QUIET
? @$this->native($func, $path)
: $this->native($func, $path);
return $this->native($func, $path);
} catch (\RuntimeException $e) {
// SplFileInfo::isFile throws exception
return false;
} finally {
if ($flags & STREAM_URL_STAT_QUIET) {
restore_error_handler();
}
}
}

Expand Down
76 changes: 76 additions & 0 deletions tests/BypassFinals/overloaded.exists_check.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

// test that overloaded "exists-check" functions (see php-src/ext/standard/filestat.c) must not invoke the error handler

declare(strict_types=1);

use Tester\Assert;

require __DIR__ . '/../../vendor/autoload.php';

Tester\Environment::setup();

DG\BypassFinals::enable();


function thoroughErrorHandler(): void
{
throw new Exception('This must not happen');
}


Assert::noError(function () {
set_error_handler('thoroughErrorHandler');

file_exists('unknown');

restore_error_handler();
});

Assert::noError(function () {
set_error_handler('thoroughErrorHandler');

is_writable('unknown');

restore_error_handler();
});

Assert::noError(function () {
set_error_handler('thoroughErrorHandler');

is_readable('unknown');

restore_error_handler();
});

Assert::noError(function () {
set_error_handler('thoroughErrorHandler');

is_executable('unknown');

restore_error_handler();
});

Assert::noError(function () {
set_error_handler('thoroughErrorHandler');

is_file('unknown');

restore_error_handler();
});

Assert::noError(function () {
set_error_handler('thoroughErrorHandler');

is_dir('unknown');

restore_error_handler();
});

Assert::noError(function () {
set_error_handler('thoroughErrorHandler');

is_link('unknown');

restore_error_handler();
});

0 comments on commit 91770cc

Please sign in to comment.