diff --git a/core/block.php b/core/block.php
index bd433229..65b115b5 100644
--- a/core/block.php
+++ b/core/block.php
@@ -55,7 +55,7 @@ class Block
if (is_null($id)) {
$id = (empty($header) ? md5($this->body ?? '') : $header) . $section;
}
- $str_id = preg_replace('/[^\w-]/', '', str_replace(' ', '_', $id));
+ $str_id = preg_replace_ex('/[^\w-]/', '', str_replace(' ', '_', $id));
assert(is_string($str_id));
$this->id = $str_id;
}
diff --git a/core/database.php b/core/database.php
index bd8799d6..d18136a1 100644
--- a/core/database.php
+++ b/core/database.php
@@ -185,8 +185,7 @@ class Database
global $_tracer, $tracer_enabled;
$dur = ftime() - $start;
// trim whitespace
- $query = \Safe\preg_replace('/[\n\t ]+/m', ' ', $query);
- assert(is_string($query));
+ $query = preg_replace_ex('/[\n\t ]+/m', ' ', $query);
$query = trim($query);
if ($tracer_enabled) {
$_tracer->complete($start * 1000000, $dur * 1000000, "DB Query", ["query" => $query, "args" => $args, "method" => $method]);
diff --git a/core/imageboard/tag.php b/core/imageboard/tag.php
index fab6b1f2..95c266cc 100644
--- a/core/imageboard/tag.php
+++ b/core/imageboard/tag.php
@@ -196,13 +196,13 @@ class Tag
public static function sanitize(string $tag): string
{
- $tag = preg_replace("/\s/", "", $tag); # whitespace
+ $tag = preg_replace_ex("/\s/", "", $tag); # whitespace
assert($tag !== null);
- $tag = preg_replace('/\x20[\x0e\x0f]/', '', $tag); # unicode RTL
+ $tag = preg_replace_ex('/\x20[\x0e\x0f]/', '', $tag); # unicode RTL
assert($tag !== null);
- $tag = preg_replace("/\.+/", ".", $tag); # strings of dots?
+ $tag = preg_replace_ex("/\.+/", ".", $tag); # strings of dots?
assert($tag !== null);
- $tag = preg_replace("/^(\.+[\/\\\\])+/", "", $tag); # trailing slashes?
+ $tag = preg_replace_ex("/^(\.+[\/\\\\])+/", "", $tag); # trailing slashes?
assert($tag !== null);
$tag = trim($tag, ", \t\n\r\0\x0B");
diff --git a/core/polyfills.php b/core/polyfills.php
index 8c71e523..30ce6b97 100644
--- a/core/polyfills.php
+++ b/core/polyfills.php
@@ -693,8 +693,7 @@ function validate_input(array $inputs): array
*/
function sanitize_path(string $path): string
{
- $r = \Safe\preg_replace('|[\\\\/]+|S', DIRECTORY_SEPARATOR, $path);
- assert(is_string($r));
+ $r = preg_replace_ex('|[\\\\/]+|S', DIRECTORY_SEPARATOR, $path);
return $r;
}
diff --git a/core/send_event.php b/core/send_event.php
index 553a4b15..79c72416 100644
--- a/core/send_event.php
+++ b/core/send_event.php
@@ -21,7 +21,7 @@ function _load_event_listeners(): void
{
global $_shm_event_listeners;
- $ver = preg_replace("/[^a-zA-Z0-9\.]/", "_", VERSION);
+ $ver = preg_replace_ex("/[^a-zA-Z0-9\.]/", "_", VERSION);
$key = md5(Extension::get_enabled_extensions_as_string());
$cache_path = data_path("cache/event_listeners/el.$ver.$key.php");
diff --git a/core/stdlib_ex.php b/core/stdlib_ex.php
index 99169412..69c87b33 100644
--- a/core/stdlib_ex.php
+++ b/core/stdlib_ex.php
@@ -32,3 +32,12 @@ function filter_var_ex(mixed $variable, int $filter = FILTER_DEFAULT, mixed $opt
{
return false_throws(filter_var($variable, $filter, $options));
}
+
+function preg_replace_ex(string $pattern, string $replacement, string $subject, int $limit = -1, ?int &$count = null): string
+{
+ $res = preg_replace($pattern, $replacement, $subject, $limit, $count);
+ if (is_null($res)) {
+ throw new \Exception("preg_replace failed");
+ }
+ return $res;
+}
diff --git a/ext/bbcode/main.php b/ext/bbcode/main.php
index e8c6941d..35dc0fd1 100644
--- a/ext/bbcode/main.php
+++ b/ext/bbcode/main.php
@@ -18,36 +18,36 @@ class BBCode extends FormatterExtension
foreach ([
"b", "i", "u", "s", "sup", "sub", "h1", "h2", "h3", "h4",
] as $el) {
- $text = preg_replace("!\[$el\](.*?)\[/$el\]!s", "<$el>$1$el>", $text);
+ $text = preg_replace_ex("!\[$el\](.*?)\[/$el\]!s", "<$el>$1$el>", $text);
}
- $text = preg_replace('!^>>([^\d].+)!', '
$1
', $text);
- $text = preg_replace('!>>(\d+)(#c?\d+)?!s', '>>$1$2', $text);
- $text = preg_replace('!\[anchor=(.*?)\](.*?)\[/anchor\]!s', '$2 ¶ ', $text); // add "bb-" to avoid clashing with eg #top
- $text = preg_replace('!\[url=site://(.*?)(#c\d+)?\](.*?)\[/url\]!s', '$3', $text);
- $text = preg_replace('!\[url\]site://(.*?)(#c\d+)?\[/url\]!s', '$1$2', $text);
- $text = preg_replace('!\[url=((?:https?|ftp|irc|mailto)://.*?)\](.*?)\[/url\]!s', '$2', $text);
- $text = preg_replace('!\[url\]((?:https?|ftp|irc|mailto)://.*?)\[/url\]!s', '$1', $text);
- $text = preg_replace('!\[email\](.*?)\[/email\]!s', '$1', $text);
- $text = preg_replace('!\[img\](https?:\/\/.*?)\[/img\]!s', '', $text);
- $text = preg_replace('!\[\[([^\|\]]+)\|([^\]]+)\]\]!s', '$2', $text);
- $text = preg_replace('!\[\[([^\]]+)\]\]!s', '$1', $text);
- $text = preg_replace("!\n\s*\n!", "\n\n", $text);
+ $text = preg_replace_ex('!^>>([^\d].+)!', '$1
', $text);
+ $text = preg_replace_ex('!>>(\d+)(#c?\d+)?!s', '>>$1$2', $text);
+ $text = preg_replace_ex('!\[anchor=(.*?)\](.*?)\[/anchor\]!s', '$2 ¶ ', $text); // add "bb-" to avoid clashing with eg #top
+ $text = preg_replace_ex('!\[url=site://(.*?)(#c\d+)?\](.*?)\[/url\]!s', '$3', $text);
+ $text = preg_replace_ex('!\[url\]site://(.*?)(#c\d+)?\[/url\]!s', '$1$2', $text);
+ $text = preg_replace_ex('!\[url=((?:https?|ftp|irc|mailto)://.*?)\](.*?)\[/url\]!s', '$2', $text);
+ $text = preg_replace_ex('!\[url\]((?:https?|ftp|irc|mailto)://.*?)\[/url\]!s', '$1', $text);
+ $text = preg_replace_ex('!\[email\](.*?)\[/email\]!s', '$1', $text);
+ $text = preg_replace_ex('!\[img\](https?:\/\/.*?)\[/img\]!s', '', $text);
+ $text = preg_replace_ex('!\[\[([^\|\]]+)\|([^\]]+)\]\]!s', '$2', $text);
+ $text = preg_replace_ex('!\[\[([^\]]+)\]\]!s', '$1', $text);
+ $text = preg_replace_ex("!\n\s*\n!", "\n\n", $text);
$text = str_replace("\n", "\n
", $text);
- $text = preg_replace("/\[quote\](.*?)\[\/quote\]/s", "\\1
", $text);
- $text = preg_replace("/\[quote=(.*?)\](.*?)\[\/quote\]/s", "\\1 said:
\\2
", $text);
+ $text = preg_replace_ex("/\[quote\](.*?)\[\/quote\]/s", "\\1
", $text);
+ $text = preg_replace_ex("/\[quote=(.*?)\](.*?)\[\/quote\]/s", "\\1 said:
\\2
", $text);
while (preg_match("/\[list\](.*?)\[\/list\]/s", $text)) {
- $text = preg_replace("/\[list\](.*?)\[\/list\]/s", "", $text);
+ $text = preg_replace_ex("/\[list\](.*?)\[\/list\]/s", "", $text);
}
while (preg_match("/\[ul\](.*?)\[\/ul\]/s", $text)) {
- $text = preg_replace("/\[ul\](.*?)\[\/ul\]/s", "", $text);
+ $text = preg_replace_ex("/\[ul\](.*?)\[\/ul\]/s", "", $text);
}
while (preg_match("/\[ol\](.*?)\[\/ol\]/s", $text)) {
- $text = preg_replace("/\[ol\](.*?)\[\/ol\]/s", "\\1
", $text);
+ $text = preg_replace_ex("/\[ol\](.*?)\[\/ol\]/s", "\\1
", $text);
}
- $text = preg_replace("/\[li\](.*?)\[\/li\]/s", "\\1", $text);
- $text = preg_replace("#\[\*\]#s", "", $text);
- $text = preg_replace("#
<(li|ul|ol|/ul|/ol)>#s", "<\\1>", $text);
- $text = preg_replace("#\[align=(left|center|right)\](.*?)\[\/align\]#s", "\\2
", $text);
+ $text = preg_replace_ex("/\[li\](.*?)\[\/li\]/s", "\\1", $text);
+ $text = preg_replace_ex("#\[\*\]#s", "", $text);
+ $text = preg_replace_ex("#
<(li|ul|ol|/ul|/ol)>#s", "<\\1>", $text);
+ $text = preg_replace_ex("#\[align=(left|center|right)\](.*?)\[\/align\]#s", "\\2
", $text);
$text = $this->filter_spoiler($text);
$text = $this->insert_code($text);
return $text;
@@ -59,17 +59,17 @@ class BBCode extends FormatterExtension
"b", "i", "u", "s", "sup", "sub", "h1", "h2", "h3", "h4",
"code", "url", "email", "li",
] as $el) {
- $text = preg_replace("!\[$el\](.*?)\[/$el\]!s", '$1', $text);
+ $text = preg_replace_ex("!\[$el\](.*?)\[/$el\]!s", '$1', $text);
}
- $text = preg_replace("!\[anchor=(.*?)\](.*?)\[/anchor\]!s", '$2', $text);
- $text = preg_replace("!\[url=(.*?)\](.*?)\[/url\]!s", '$2', $text);
- $text = preg_replace("!\[img\](.*?)\[/img\]!s", "", $text);
- $text = preg_replace("!\[\[([^\|\]]+)\|([^\]]+)\]\]!s", '$2', $text);
- $text = preg_replace("!\[\[([^\]]+)\]\]!s", '$1', $text);
- $text = preg_replace("!\[quote\](.*?)\[/quote\]!s", "", $text);
- $text = preg_replace("!\[quote=(.*?)\](.*?)\[/quote\]!s", "", $text);
- $text = preg_replace("!\[/?(list|ul|ol)\]!", "", $text);
- $text = preg_replace("!\[\*\](.*?)!s", '$1', $text);
+ $text = preg_replace_ex("!\[anchor=(.*?)\](.*?)\[/anchor\]!s", '$2', $text);
+ $text = preg_replace_ex("!\[url=(.*?)\](.*?)\[/url\]!s", '$2', $text);
+ $text = preg_replace_ex("!\[img\](.*?)\[/img\]!s", "", $text);
+ $text = preg_replace_ex("!\[\[([^\|\]]+)\|([^\]]+)\]\]!s", '$2', $text);
+ $text = preg_replace_ex("!\[\[([^\]]+)\]\]!s", '$1', $text);
+ $text = preg_replace_ex("!\[quote\](.*?)\[/quote\]!s", "", $text);
+ $text = preg_replace_ex("!\[quote=(.*?)\](.*?)\[/quote\]!s", "", $text);
+ $text = preg_replace_ex("!\[/?(list|ul|ol)\]!", "", $text);
+ $text = preg_replace_ex("!\[\*\](.*?)!s", '$1', $text);
$text = $this->strip_spoiler($text);
return $text;
}
diff --git a/ext/emoticons/main.php b/ext/emoticons/main.php
index 2f8d4702..5c8a8aca 100644
--- a/ext/emoticons/main.php
+++ b/ext/emoticons/main.php
@@ -12,7 +12,7 @@ class Emoticons extends FormatterExtension
public function format(string $text): string
{
$data_href = get_base_href();
- $text = preg_replace("/:([a-z]*?):/s", "", $text);
+ $text = preg_replace_ex("/:([a-z]*?):/s", "", $text);
return $text;
}
diff --git a/ext/et/main.php b/ext/et/main.php
index ba1d33d5..94e75266 100644
--- a/ext/et/main.php
+++ b/ext/et/main.php
@@ -123,7 +123,7 @@ class ET extends Extension
$commitHash = trim(\Safe\exec('git log --pretty="%h" -n1 HEAD'));
$commitBranch = trim(\Safe\exec('git rev-parse --abbrev-ref HEAD'));
$commitOrigin = trim(\Safe\exec('git config --get remote.origin.url'));
- $commitOrigin = preg_replace("#//.*@#", "//xxx@", $commitOrigin);
+ $commitOrigin = preg_replace_ex("#//.*@#", "//xxx@", $commitOrigin);
$info['versions']['shimmie'] .= $commitHash;
$info['versions']['origin'] = "$commitOrigin ($commitBranch)";
$info['git'] = [
diff --git a/ext/image/main.php b/ext/image/main.php
index e4859060..996bba8a 100644
--- a/ext/image/main.php
+++ b/ext/image/main.php
@@ -244,7 +244,7 @@ class ImageIO extends Extension
if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
- $if_modified_since = preg_replace('/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"]);
+ $if_modified_since = preg_replace_ex('/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"]);
} else {
$if_modified_since = "";
}
diff --git a/ext/index/main.php b/ext/index/main.php
index d3aa54ca..6d874ebd 100644
--- a/ext/index/main.php
+++ b/ext/index/main.php
@@ -174,7 +174,7 @@ class Index extends Extension
);
$sql_str = $q->sql;
- $sql_str = preg_replace("/\s+/", " ", $sql_str);
+ $sql_str = preg_replace_ex("/\s+/", " ", $sql_str);
foreach ($q->variables as $key => $val) {
if (is_string($val)) {
$sql_str = str_replace(":$key", "'$val'", $sql_str);
diff --git a/ext/media/main.php b/ext/media/main.php
index deefb325..0660c952 100644
--- a/ext/media/main.php
+++ b/ext/media/main.php
@@ -252,7 +252,7 @@ class Media extends Extension
$event->add_querylet(new Querylet("$field = :true", ["true" => true]));
}
} elseif (preg_match("/^ratio([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+):(\d+)$/i", $event->term, $matches)) {
- $cmp = preg_replace('/^:/', '=', $matches[1]);
+ $cmp = preg_replace_ex('/^:/', '=', $matches[1]);
$args = ["width{$event->id}" => int_escape($matches[2]), "height{$event->id}" => int_escape($matches[3])];
$event->add_querylet(new Querylet("width / :width{$event->id} $cmp height / :height{$event->id}", $args));
} elseif (preg_match("/^size([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)x(\d+)$/i", $event->term, $matches)) {
diff --git a/ext/static_files/main.php b/ext/static_files/main.php
index 0f05d73f..a13004ba 100644
--- a/ext/static_files/main.php
+++ b/ext/static_files/main.php
@@ -36,7 +36,7 @@ class StaticFiles extends Extension
// hax.
if ($page->mode == PageMode::PAGE && (!isset($page->blocks) || $this->count_main($page->blocks) == 0)) {
$h_pagename = html_escape(implode('/', $event->args));
- $f_pagename = preg_replace("/[^a-z_\-\.]+/", "_", $h_pagename);
+ $f_pagename = preg_replace_ex("/[^a-z_\-\.]+/", "_", $h_pagename);
$theme_name = $config->get_string(SetupConfig::THEME, "default");
$theme_file = "themes/$theme_name/static/$f_pagename";
diff --git a/ext/upload/main.php b/ext/upload/main.php
index 7470e84d..e88fa01c 100644
--- a/ext/upload/main.php
+++ b/ext/upload/main.php
@@ -351,7 +351,7 @@ class Upload extends Extension
// Parse metadata
$s_filename = find_header($headers, 'Content-Disposition');
- $h_filename = ($s_filename ? preg_replace('/^.*filename="([^ ]+)"/i', '$1', $s_filename) : null);
+ $h_filename = ($s_filename ? preg_replace_ex('/^.*filename="([^ ]+)"/i', '$1', $s_filename) : null);
$filename = $h_filename ?: basename($url);
$new_images = $database->with_savepoint(function () use ($tmp_filename, $filename, $slot, $metadata) {
diff --git a/ext/user/theme.php b/ext/user/theme.php
index 4b75004d..f77209fb 100644
--- a/ext/user/theme.php
+++ b/ext/user/theme.php
@@ -402,7 +402,7 @@ class UserPageTheme extends Themelet
$doc = $perm->getDocComment();
if ($doc) {
- $doc = preg_replace('/\/\*\*|\n\s*\*\s*|\*\//', '', $doc);
+ $doc = preg_replace_ex('/\/\*\*|\n\s*\*\s*|\*\//', '', $doc);
$row->appendChild(TD(["style" => "text-align: left;"], $doc));
} else {
$row->appendChild(TD(""));
diff --git a/ext/user_config/theme.php b/ext/user_config/theme.php
index 69f410b2..46c1a866 100644
--- a/ext/user_config/theme.php
+++ b/ext/user_config/theme.php
@@ -75,7 +75,7 @@ class UserConfigTheme extends Themelet
{
$h = $block->header;
$b = $block->body;
- $i = preg_replace('/[^a-zA-Z0-9]/', '_', $h) . "-setup";
+ $i = preg_replace_ex('/[^a-zA-Z0-9]/', '_', $h) . "-setup";
$html = "
$h
diff --git a/ext/word_filter/main.php b/ext/word_filter/main.php
index b456a24f..b73a35d5 100644
--- a/ext/word_filter/main.php
+++ b/ext/word_filter/main.php
@@ -32,10 +32,10 @@ class WordFilter extends Extension
$search = trim($search);
$replace = trim($replace);
if ($search[0] == '/') {
- $text = preg_replace($search, $replace, $text);
+ $text = preg_replace_ex($search, $replace, $text);
} else {
$search = "/\\b" . str_replace("/", "\\/", $search) . "\\b/i";
- $text = preg_replace($search, $replace, $text);
+ $text = preg_replace_ex($search, $replace, $text);
}
}
return $text;
diff --git a/themes/futaba/comment.theme.php b/themes/futaba/comment.theme.php
index 5bbd62e1..ed75af6a 100644
--- a/themes/futaba/comment.theme.php
+++ b/themes/futaba/comment.theme.php
@@ -87,7 +87,7 @@ class CustomCommentListTheme extends CommentListTheme
} else {
$h_comment = $tfe->formatted;
}
- $h_comment = preg_replace("/(^|>)(>[^<\n]*)(<|\n|$)/", '${1}${2}${3}', $h_comment);
+ $h_comment = preg_replace_ex("/(^|>)(>[^<\n]*)(<|\n|$)/", '${1}${2}${3}', $h_comment);
// handles discrepency in comment page and homepage
$h_comment = str_replace("
", "", $h_comment);
$h_comment = str_replace("\n", "
", $h_comment);