PluginProbe
404 Solution / trunk
404 Solution vtrunk
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / includes / redirects / RegexSourcePatternValidator.php

RegexSourcePatternValidator.php in 404 Solution trunk, at includes/redirects/RegexSourcePatternValidator.php

52 lines 1.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) {
4 exit;
5 }
6
7 /**
8 * Compiles redirect source patterns at every write boundary.
9 *
10 * This shared validator contains no presentation concerns so admin handlers,
11 * imports, REST/WP-CLI writes, and the repository can enforce one contract.
12 */
13 final class ABJ_404_Solution_RegexSourcePatternValidator {
14
15 /** @var ABJ_404_Solution_Functions */
16 private $functions;
17
18 /**
19 * @param ABJ_404_Solution_Functions $functions
20 */
21 public function __construct($functions) {
22 $this->functions = $functions;
23 }
24
25 /**
26 * @return array{valid: bool, detail: string}
27 */
28 public function validate(string $pattern): array {
29 if ($pattern === '') {
30 return array('valid' => false, 'detail' => 'Source pattern is empty.');
31 }
32 if (preg_match('/[\x00-\x1F\x7F]/', $pattern) === 1) {
33 return array('valid' => false, 'detail' => 'Source pattern contains control characters.');
34 }
35
36 $warning = '';
37 set_error_handler(static function($severity, $message) use (&$warning) {
38 $warning = $message;
39 return true;
40 });
41 try {
42 $this->functions->regexMatch($pattern, '');
43 } catch (Throwable $error) { // allow-silent-catch: the original regex engine error is returned in detail below.
44 $warning = $error->getMessage();
45 } finally {
46 restore_error_handler();
47 }
48
49 return array('valid' => $warning === '', 'detail' => $warning);
50 }
51 }
52