diff --git a/web/configs/version.json b/web/configs/version.json index 48147b0dc..ef0e2ebe9 100644 --- a/web/configs/version.json +++ b/web/configs/version.json @@ -1,5 +1,5 @@ { "version": "1.8.0", - "git": "1411", + "git": "1420", "dev": true } diff --git a/web/includes/system-functions.php b/web/includes/system-functions.php index 90d0c0d09..625f45af2 100644 --- a/web/includes/system-functions.php +++ b/web/includes/system-functions.php @@ -405,3 +405,23 @@ function compareSanitizedString(string $str1, string $str2) { return (bool)(strcmp(filter_var($str1, FILTER_SANITIZE_SPECIAL_CHARS), filter_var($str2, FILTER_SANITIZE_SPECIAL_CHARS)) === 0); } + +/** + * @param string $text + * @return string + */ +function encodePreservingBr($text) { + // Split the text at
tags, preserving the tags in the result + $parts = preg_split('/()/i', $text, -1, PREG_SPLIT_DELIM_CAPTURE); + $result = ''; + + foreach ($parts as $part) { + if (preg_match('/^$/i', $part)) { + $result .= "\n"; // Replace
with newline + } else { + $result .= htmlspecialchars($part, ENT_QUOTES, 'UTF-8'); // Encode the rest + } + } + + return nl2br($result); // Convert newlines back to
for HTML +} \ No newline at end of file diff --git a/web/pages/admin.bans.php b/web/pages/admin.bans.php index 1b3620720..ead17541c 100644 --- a/web/pages/admin.bans.php +++ b/web/pages/admin.bans.php @@ -239,8 +239,10 @@ $cdata['comname'] = $commentres->fields['comname']; $cdata['added'] = Config::time($commentres->fields['added']); - $cdata['commenttxt'] = htmlspecialchars($commentres->fields['commenttxt']); - $cdata['commenttxt'] = str_replace("\n", "
", $cdata['commenttxt']); + $commentText = html_entity_decode($commentres->fields['commenttxt'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $commentText = encodePreservingBr($commentText); + $commentText = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '\$1', $commentText); + $cdata['commenttxt'] = $commentText; if (!empty($commentres->fields['edittime'])) { $cdata['edittime'] = Config::time($commentres->fields['edittime']); @@ -400,8 +402,10 @@ $cdata['comname'] = $commentres->fields['comname']; $cdata['added'] = Config::time($commentres->fields['added']); - $cdata['commenttxt'] = htmlspecialchars($commentres->fields['commenttxt']); - $cdata['commenttxt'] = str_replace("\n", "
", $cdata['commenttxt']); + $commentText = html_entity_decode($commentres->fields['commenttxt'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $commentText = encodePreservingBr($commentText); + $commentText = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '\$1', $commentText); + $cdata['commenttxt'] = $commentText; if (!empty($commentres->fields['edittime'])) { $cdata['edittime'] = Config::time($commentres->fields['edittime']); @@ -554,8 +558,11 @@ $cdata['comname'] = $commentres->fields['comname']; $cdata['added'] = Config::time($commentres->fields['added']); - $cdata['commenttxt'] = htmlspecialchars($commentres->fields['commenttxt']); - $cdata['commenttxt'] = str_replace("\n", "
", $cdata['commenttxt']); + $commentText = html_entity_decode($commentres->fields['commenttxt'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $commentText = encodePreservingBr($commentText); + // Parse links and wrap them in a tag to be easily clickable + $commentText = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '\$1', $commentText); + $cdata['commenttxt'] = $commentText; if (!empty($commentres->fields['edittime'])) { $cdata['edittime'] = Config::time($commentres->fields['edittime']); @@ -694,8 +701,11 @@ $cdata['comname'] = $commentres->fields['comname']; $cdata['added'] = Config::time($commentres->fields['added']); - $cdata['commenttxt'] = htmlspecialchars($commentres->fields['commenttxt']); - $cdata['commenttxt'] = str_replace("\n", "
", $cdata['commenttxt']); + $commentText = html_entity_decode($commentres->fields['commenttxt'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $commentText = encodePreservingBr($commentText); + // Parse links and wrap them in a tag to be easily clickable + $commentText = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '\$1', $commentText); + $cdata['commenttxt'] = $commentText; if (!empty($commentres->fields['edittime'])) { $cdata['edittime'] = Config::time($commentres->fields['edittime']); diff --git a/web/pages/page.banlist.php b/web/pages/page.banlist.php index 9640c6286..6f3ea1f8a 100644 --- a/web/pages/page.banlist.php +++ b/web/pages/page.banlist.php @@ -647,10 +647,11 @@ function setPostKey() $cdata['comname'] = $commentres->fields['comname']; $cdata['added'] = Config::time($commentres->fields['added']); - $cdata['commenttxt'] = htmlspecialchars($commentres->fields['commenttxt']); - $cdata['commenttxt'] = str_replace("\n", "
", $cdata['commenttxt']); + $commentText = html_entity_decode($commentres->fields['commenttxt'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $commentText = encodePreservingBr($commentText); // Parse links and wrap them in a tag to be easily clickable - $cdata['commenttxt'] = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '$1', $cdata['commenttxt']); + $commentText = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '\$1', $commentText); + $cdata['commenttxt'] = $commentText; if (!empty($commentres->fields['edittime'])) { $cdata['edittime'] = Config::time($commentres->fields['edittime']); @@ -742,7 +743,8 @@ function setPostKey() if (isset($_GET["cid"])) { $_GET["cid"] = (int) $_GET["cid"]; $ceditdata = $GLOBALS['db']->GetRow("SELECT * FROM " . DB_PREFIX . "_comments WHERE cid = '" . $_GET["cid"] . "'"); - $ctext = htmlspecialchars($ceditdata['commenttxt']); + $ctext = html_entity_decode($ceditdata['commenttxt'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $ctext = htmlspecialchars($ctext, ENT_QUOTES | ENT_HTML5, 'UTF-8'); $cotherdataedit = " AND cid != '" . $_GET["cid"] . "'"; } else { $cotherdataedit = ""; @@ -765,10 +767,12 @@ function setPostKey() $coment = []; $coment['comname'] = $cotherdata->fields['comname']; $coment['added'] = Config::time($cotherdata->fields['added']); - $coment['commenttxt'] = htmlspecialchars($cotherdata->fields['commenttxt']); - $coment['commenttxt'] = str_replace("\n", "
", $coment['commenttxt']); + $commentText = html_entity_decode($cotherdata->fields['commenttxt'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $commentText = encodePreservingBr($commentText); // Parse links and wrap them in a tag to be easily clickable - $coment['commenttxt'] = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '$1', $coment['commenttxt']); + $commentText = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '\$1', $commentText); + $coment['commenttxt'] = $commentText; + if ($cotherdata->fields['editname'] != "") { $coment['edittime'] = Config::time($cotherdata->fields['edittime']); $coment['editname'] = $cotherdata->fields['editname']; @@ -812,4 +816,4 @@ function setPostKey() $theme->assign('can_delete', $userbank->HasAccess(ADMIN_DELETE_BAN)); $theme->assign('view_bans', ($userbank->HasAccess(ADMIN_OWNER | ADMIN_EDIT_ALL_BANS | ADMIN_EDIT_OWN_BANS | ADMIN_EDIT_GROUP_BANS | ADMIN_UNBAN | ADMIN_UNBAN_OWN_BANS | ADMIN_UNBAN_GROUP_BANS | ADMIN_DELETE_BAN))); $theme->assign('can_export', ($userbank->HasAccess(ADMIN_OWNER) || Config::getBool('config.exportpublic'))); -$theme->display('page_bans.tpl'); +$theme->display('page_bans.tpl'); \ No newline at end of file diff --git a/web/pages/page.commslist.php b/web/pages/page.commslist.php index 60c8b713d..9eb1135ef 100644 --- a/web/pages/page.commslist.php +++ b/web/pages/page.commslist.php @@ -607,10 +607,11 @@ function setPostKey() $cdata['comname'] = $commentres->fields['comname']; $cdata['added'] = Config::time($commentres->fields['added']); - $cdata['commenttxt'] = $commentres->fields['commenttxt']; - $cdata['commenttxt'] = str_replace("\n", "
", $cdata['commenttxt']); + $commentText = html_entity_decode($commentres->fields['commenttxt'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $commentText = encodePreservingBr($commentText); // Parse links and wrap them in a tag to be easily clickable - $cdata['commenttxt'] = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '$1', $cdata['commenttxt']); + $commentText = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '\$1', $commentText); + $cdata['commenttxt'] = $commentText; if (!empty($commentres->fields['edittime'])) { $cdata['edittime'] = Config::time($commentres->fields['edittime']); @@ -700,7 +701,8 @@ function setPostKey() $theme->assign('commenttype', (isset($_GET["cid"]) ? "Edit" : "Add")); if (isset($_GET["cid"])) { $ceditdata = $GLOBALS['db']->GetRow("SELECT * FROM " . DB_PREFIX . "_comments WHERE cid = '" . (int) $_GET["cid"] . "'"); - $ctext = $ceditdata['commenttxt']; + $ctext = html_entity_decode($ceditdata['commenttxt'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $ctext = htmlspecialchars($ctext, ENT_QUOTES | ENT_HTML5, 'UTF-8'); $cotherdataedit = " AND cid != '" . (int) $_GET["cid"] . "'"; } else { $cotherdataedit = ""; @@ -720,9 +722,10 @@ function setPostKey() $coment = []; $coment['comname'] = $cotherdata->fields['comname']; $coment['added'] = Config::time($cotherdata->fields['added']); - $coment['commenttxt'] = str_replace("\n", "
", $cotherdata->fields['commenttxt']); - // Parse links and wrap them in a tag to be easily clickable - $coment['commenttxt'] = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '$1', $coment['commenttxt']); + $commentText = html_entity_decode($cotherdata->fields['commenttxt'], ENT_QUOTES | ENT_HTML5, 'UTF-8'); + $commentText = encodePreservingBr($commentText); + $commentText = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '\$1', $commentText); + $coment['commenttxt'] = $commentText; if ($cotherdata->fields['editname'] != "") { $coment['edittime'] = Config::time($cotherdata->fields['edittime']); $coment['editname'] = $cotherdata->fields['editname'];