diff --git a/RoboFile.php b/RoboFile.php index ee4c74a..e2ea42a 100644 --- a/RoboFile.php +++ b/RoboFile.php @@ -218,7 +218,7 @@ class RoboFile extends \Robo\Tasks { // Remove files which lintian complains about; they're otherwise harmless $files = []; foreach (new \CallbackFilterIterator(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir."vendor", \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS)), function($v, $k, $i) { - return preg_match('/\/\.git(?:ignore|attributes|modules)$/', $v); + return preg_match('/\/\.git(?:ignore|attributes|modules)$/D', $v); }) as $f) { $files[] = $f; } @@ -356,9 +356,9 @@ class RoboFile extends \Robo\Tasks { $expected = ["version"]; for ($a = 0; $a < sizeof($lines);) { $l = rtrim($lines[$a++]); - if (in_array("version", $expected) && preg_match('/^Version (\d+(?:\.\d+)*) \(([\d\?]{4}-[\d\?]{2}-[\d\?]{2})\)\s*$/', $l, $m)) { + if (in_array("version", $expected) && preg_match('/^Version (\d+(?:\.\d+)*) \(([\d\?]{4}-[\d\?]{2}-[\d\?]{2})\)\s*$/D', $l, $m)) { $version = $m[1]; - if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $m[2])) { + if (!preg_match('/^\d{4}-\d{2}-\d{2}$/D', $m[2])) { // uncertain dates are allowed only for the top version, and only if it does not match the target version (otherwise we have forgotten to set the correct date before tagging) if (!$out && $targetVersion !== $version) { // use today's date; local time is fine @@ -398,10 +398,10 @@ class RoboFile extends \Robo\Tasks { } elseif (in_array("changes section", $expected) && $l === "Changes:") { $section = "changes"; $expected = ["item"]; - } elseif (in_array("item", $expected) && preg_match('/^- (\w.*)$/', $l, $m)) { + } elseif (in_array("item", $expected) && preg_match('/^- (\w.*)$/D', $l, $m)) { $entry[$section][] = $m[1]; $expected = ["item", "continuation", "blank line"]; - } elseif (in_array("continuation", $expected) && preg_match('/^ (\w.*)$/', $l, $m)) { + } elseif (in_array("continuation", $expected) && preg_match('/^ (\w.*)$/D', $l, $m)) { $last = sizeof($entry[$section]) - 1; $entry[$section][$last] .= "\n".$m[1]; } else { @@ -436,7 +436,7 @@ class RoboFile extends \Robo\Tasks { $out = ""; foreach ($log as $entry) { // normalize the version string - preg_match('/^(\d+(?:\.\d+)*)(?:-(\d+)-.+)?$/', $entry['version'], $m); + preg_match('/^(\d+(?:\.\d+)*)(?:-(\d+)-.+)?$/D', $entry['version'], $m); $version = $m[1]."-".($m[2] ?: "1"); // output the entry $out .= "arsse ($version) UNRELEASED; urgency=low\n"; diff --git a/lib/Db/MySQL/Driver.php b/lib/Db/MySQL/Driver.php index d2c538b..9acd1ea 100644 --- a/lib/Db/MySQL/Driver.php +++ b/lib/Db/MySQL/Driver.php @@ -224,7 +224,7 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver { // with MySQL each table must be analyzed separately, so we first have to get a list of tables foreach ($this->query("SHOW TABLES like 'arsse\\_%'") as $table) { $table = array_pop($table); - if (!preg_match("/^arsse_[a-z_]+$/", $table)) { + if (!preg_match("/^arsse_[a-z_]+$/D", $table)) { // table is not one of ours continue; // @codeCoverageIgnore } diff --git a/lib/Misc/HTTP.php b/lib/Misc/HTTP.php index 15bfce9..ac41506 100644 --- a/lib/Misc/HTTP.php +++ b/lib/Misc/HTTP.php @@ -12,7 +12,7 @@ class HTTP { public static function matchType(MessageInterface $msg, string ...$type): bool { $header = $msg->getHeaderLine("Content-Type") ?? ""; foreach ($type as $t) { - $pattern = "/^".preg_quote(trim($t), "/")."\s*($|;|,)/i"; + $pattern = "/^".preg_quote(trim($t), "/")."\s*($|;|,)/Di"; if (preg_match($pattern, $header)) { return true; } diff --git a/lib/Misc/URL.php b/lib/Misc/URL.php index df16e6f..a1cad01 100644 --- a/lib/Misc/URL.php +++ b/lib/Misc/URL.php @@ -78,7 +78,7 @@ class URL { if ($c === "%") { // the % character signals an encoded character... $d = substr($part, $pos + 1, 2); - if (!preg_match("/^[0-9a-fA-F]{2}$/", $d)) { + if (!preg_match("/^[0-9a-fA-F]{2}$/D", $d)) { // unless there are fewer than two characters left in the string or the two characters are not hex digits $d = ord($c); } else { diff --git a/lib/Misc/ValueInfo.php b/lib/Misc/ValueInfo.php index 688a394..0aba770 100644 --- a/lib/Misc/ValueInfo.php +++ b/lib/Misc/ValueInfo.php @@ -222,7 +222,7 @@ class ValueInfo { return $out; } else { $out = sprintf("%F", $value); - return preg_match("/\.0{1,}$/", $out) ? (string) (int) $out : $out; + return preg_match("/\.0{1,}$/D", $out) ? (string) (int) $out : $out; } } $info = self::str($value); @@ -256,7 +256,7 @@ class ValueInfo { $out = false; if ($dateInFormat === "microtime") { // PHP is not able to correctly handle the output of microtime() as the input of DateTime::createFromFormat(), so we fudge it to look like a float - if (preg_match("<^0\.\d{6}00 \d+$>", $value)) { + if (preg_match("<^0\.\d{6}00 \d+$>D", $value)) { $value = substr($value, 11).".".substr($value, 2, 6); } else { throw new \Exception; diff --git a/lib/REST.php b/lib/REST.php index 1552277..8d26628 100644 --- a/lib/REST.php +++ b/lib/REST.php @@ -118,7 +118,7 @@ class REST { // first try a simple substring match if (strpos($url, $api['match']) === 0) { // if it matches, perform a more rigorous match and then strip off any defined prefix - $pattern = "<^".preg_quote($api['match'])."([/\?#]|$)>"; + $pattern = "<^".preg_quote($api['match'])."([/\?#]|$)>D"; if ($url === $api['match'] || in_array(substr($api['match'], -1, 1), ["/", "?", "#"]) || preg_match($pattern, $url)) { $target = substr($url, strlen($api['strip'])); } else { @@ -258,7 +258,7 @@ class REST { // if the origin is the special value "null", use it return "null"; } - if (preg_match("<^([^:]+)://(\[[^\]]+\]|[^\[\]:/\?#@]+)((?::.*)?)$>i", $origin, $match)) { + if (preg_match("<^([^:]+)://(\[[^\]]+\]|[^\[\]:/\?#@]+)((?::.*)?)$>Di", $origin, $match)) { // if the origin sort-of matches the syntax in a general sense, continue $scheme = $match[1]; $host = $match[2]; @@ -266,7 +266,7 @@ class REST { // decode and normalize the scheme and port (the port may be blank) $scheme = strtolower(rawurldecode($scheme)); $port = rawurldecode($port); - if (!preg_match("<^(?::[0-9]+)?$>", $port) || !preg_match("<^[a-z](?:[a-z0-9\+\-\.])*$>", $scheme)) { + if (!preg_match("<^(?::[0-9]+)?$>D", $port) || !preg_match("<^[a-z](?:[a-z0-9\+\-\.])*$>D", $scheme)) { // if the normalized port contains anything but numbers, or the scheme does not follow the generic URL syntax, the origin is invalid return ""; } diff --git a/lib/REST/Miniflux/V1.php b/lib/REST/Miniflux/V1.php index 4c55fbc..7cba406 100644 --- a/lib/REST/Miniflux/V1.php +++ b/lib/REST/Miniflux/V1.php @@ -332,7 +332,7 @@ class V1 extends \JKingWeb\Arsse\REST\AbstractHandler { } } // handle special case "Get User By User Name", which can have any non-numeric string, non-empty as the last component - if (sizeof($path) === 3 && $path[0] === "" && $path[1] === "users" && !preg_match("/^(?:\d+)?$/", $path[2])) { + if (sizeof($path) === 3 && $path[0] === "" && $path[1] === "users" && !preg_match("/^(?:\d+)?$/D", $path[2])) { $path[2] = "*"; } return implode("/", $path); diff --git a/lib/REST/NextcloudNews/Versions.php b/lib/REST/NextcloudNews/Versions.php index 8337736..95ee0bf 100644 --- a/lib/REST/NextcloudNews/Versions.php +++ b/lib/REST/NextcloudNews/Versions.php @@ -16,7 +16,7 @@ class Versions implements \JKingWeb\Arsse\REST\Handler { } public function dispatch(ServerRequestInterface $req): ResponseInterface { - if (!preg_match("<^/?$>", $req->getRequestTarget())) { + if (!preg_match("<^/?$>D", $req->getRequestTarget())) { // if the request path is more than an empty string or a slash, the client is probably trying a version we don't support return new EmptyResponse(404); } diff --git a/lib/REST/TinyTinyRSS/API.php b/lib/REST/TinyTinyRSS/API.php index 60c4e3b..74f315a 100644 --- a/lib/REST/TinyTinyRSS/API.php +++ b/lib/REST/TinyTinyRSS/API.php @@ -94,7 +94,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler { } public function dispatch(ServerRequestInterface $req): ResponseInterface { - if (!preg_match("<^(?:/(?:index\.php)?)?$>", $req->getRequestTarget())) { + if (!preg_match("<^(?:/(?:index\.php)?)?$>D", $req->getRequestTarget())) { // reject paths other than the index return new EmptyResponse(404); } diff --git a/lib/REST/TinyTinyRSS/Icon.php b/lib/REST/TinyTinyRSS/Icon.php index 9e7c7ec..dd718bc 100644 --- a/lib/REST/TinyTinyRSS/Icon.php +++ b/lib/REST/TinyTinyRSS/Icon.php @@ -27,7 +27,7 @@ class Icon extends \JKingWeb\Arsse\REST\AbstractHandler { if ($req->getMethod() !== "GET") { // only GET requests are allowed return new Response(405, ['Allow' => "GET"]); - } elseif (!preg_match("<^(\d+)\.ico$>", $req->getRequestTarget(), $match) || !((int) $match[1])) { + } elseif (!preg_match("<^(\d+)\.ico$>D", $req->getRequestTarget(), $match) || !((int) $match[1])) { return new Response(404); } try { diff --git a/tests/cases/Db/MySQL/TestStatement.php b/tests/cases/Db/MySQL/TestStatement.php index 76c7b81..59b0177 100644 --- a/tests/cases/Db/MySQL/TestStatement.php +++ b/tests/cases/Db/MySQL/TestStatement.php @@ -23,7 +23,7 @@ class TestStatement extends \JKingWeb\Arsse\TestCase\Db\BaseStatement { case "float": return (substr($value, -2) === ".0") ? "'".substr($value, 0, strlen($value) - 2)."'" : "'$value'"; case "string": - if (preg_match("<^char\((\d+)\)$>", $value, $match)) { + if (preg_match("<^char\((\d+)\)$>D", $value, $match)) { return "'".\IntlChar::chr((int) $match[1])."'"; } return $value; diff --git a/tests/cases/Db/MySQLPDO/TestStatement.php b/tests/cases/Db/MySQLPDO/TestStatement.php index a6d0706..678300c 100644 --- a/tests/cases/Db/MySQLPDO/TestStatement.php +++ b/tests/cases/Db/MySQLPDO/TestStatement.php @@ -24,7 +24,7 @@ class TestStatement extends \JKingWeb\Arsse\TestCase\Db\BaseStatement { case "float": return (substr($value, -2) === ".0") ? "'".substr($value, 0, strlen($value) - 2)."'" : "'$value'"; case "string": - if (preg_match("<^char\((\d+)\)$>", $value, $match)) { + if (preg_match("<^char\((\d+)\)$>D", $value, $match)) { return "'".\IntlChar::chr((int) $match[1])."'"; } return $value; diff --git a/tests/cases/Db/PostgreSQL/TestStatement.php b/tests/cases/Db/PostgreSQL/TestStatement.php index 8ec5fdb..c4ecefa 100644 --- a/tests/cases/Db/PostgreSQL/TestStatement.php +++ b/tests/cases/Db/PostgreSQL/TestStatement.php @@ -23,7 +23,7 @@ class TestStatement extends \JKingWeb\Arsse\TestCase\Db\BaseStatement { case "float": return (substr($value, -2) === ".0") ? "'".substr($value, 0, strlen($value) - 2)."'" : "'$value'"; case "string": - if (preg_match("<^char\((\d+)\)$>", $value, $match)) { + if (preg_match("<^char\((\d+)\)$>D", $value, $match)) { return "U&'\\+".str_pad(dechex((int) $match[1]), 6, "0", \STR_PAD_LEFT)."'"; } return $value; diff --git a/tests/cases/Db/PostgreSQLPDO/TestStatement.php b/tests/cases/Db/PostgreSQLPDO/TestStatement.php index 8878d42..89bae7d 100644 --- a/tests/cases/Db/PostgreSQLPDO/TestStatement.php +++ b/tests/cases/Db/PostgreSQLPDO/TestStatement.php @@ -23,7 +23,7 @@ class TestStatement extends \JKingWeb\Arsse\TestCase\Db\BaseStatement { case "float": return (substr($value, -2) === ".0") ? "'".substr($value, 0, strlen($value) - 2)."'" : "'$value'"; case "string": - if (preg_match("<^char\((\d+)\)$>", $value, $match)) { + if (preg_match("<^char\((\d+)\)$>D", $value, $match)) { return "U&'\\+".str_pad(dechex((int) $match[1]), 6, "0", \STR_PAD_LEFT)."'"; } return $value;