diff --git a/README.md b/README.md
index 41cc5d6..b3d6867 100644
--- a/README.md
+++ b/README.md
@@ -81,6 +81,7 @@ support in mind.
- Set ``TINYIB_THUMBNAIL`` to ``imagemagick``.
- **Note:** GIF files will have animated thumbnails, which will often have large file sizes.
- To use TINYIB in another language, set ``TINYIB_LOCALE`` to a language code found in `locale/`.
+ - **Note:** The [mbstring](https://www.php.net/manual/en/book.mbstring.php) PHP extension must be installed and enabled for TinyIB to properly support operating on and rendering text in any language other than English.
6. [CHMOD](https://en.wikipedia.org/wiki/Chmod) write permissions to these directories:
- ./ (the directory containing TinyIB)
- ./src/
diff --git a/imgboard.php b/imgboard.php
index 9879159..7e275b0 100644
--- a/imgboard.php
+++ b/imgboard.php
@@ -306,24 +306,24 @@ if (!isset($_GET['delete']) && !isset($_GET['manage']) && (isset($_POST['name'])
if ($staffpost || !in_array('name', $hide_fields)) {
list($post['name'], $post['tripcode']) = nameAndTripcode($_POST['name']);
- $post['name'] = cleanString(substr($post['name'], 0, 75));
+ $post['name'] = cleanString(_substr($post['name'], 0, 75));
if (!$staffpost && TINYIB_MAXNAME > 0) {
- $post['name'] = substr($post['name'], 0, TINYIB_MAXNAME);
+ $post['name'] = _substr($post['name'], 0, TINYIB_MAXNAME);
}
}
if ($staffpost || !in_array('email', $hide_fields)) {
- $post['email'] = cleanString(str_replace('"', '"', substr($_POST['email'], 0, 75)));
+ $post['email'] = cleanString(str_replace('"', '"', _substr($_POST['email'], 0, 75)));
if (!$staffpost && TINYIB_MAXEMAIL > 0) {
- $post['email'] = substr($post['email'], 0, TINYIB_MAXEMAIL);
+ $post['email'] = _substr($post['email'], 0, TINYIB_MAXEMAIL);
}
}
if ($staffpost) {
$capcode = ($isadmin) ? ' ## ' . $tinyib_capcodes[0][0] . '' : ' ## ' . $tinyib_capcodes[1][0] . '';
}
if ($staffpost || !in_array('subject', $hide_fields)) {
- $post['subject'] = cleanString(substr($_POST['subject'], 0, 75));
+ $post['subject'] = cleanString(_substr($_POST['subject'], 0, 75));
if (!$staffpost && TINYIB_MAXSUBJECT > 0) {
- $post['subject'] = substr($post['subject'], 0, TINYIB_MAXSUBJECT);
+ $post['subject'] = _substr($post['subject'], 0, TINYIB_MAXSUBJECT);
}
}
if ($staffpost || !in_array('message', $hide_fields)) {
@@ -332,7 +332,7 @@ if (!isset($_GET['delete']) && !isset($_GET['manage']) && (isset($_POST['name'])
// Treat message as raw HTML
} else {
if (TINYIB_WORDBREAK > 0) {
- $post['message'] = preg_replace('/([^\s]{' . TINYIB_WORDBREAK . '})(?=[^\s])/', '$1' . TINYIB_WORDBREAK_IDENTIFIER, $post['message']);
+ $post['message'] = preg_replace('/([^\s]{' . TINYIB_WORDBREAK . '})(?=[^\s])/u', '$1' . TINYIB_WORDBREAK_IDENTIFIER, $post['message']);
}
$post['message'] = str_replace("\n", '
', makeLinksClickable(colorQuote(postLink(cleanString(rtrim($post['message']))))));
@@ -1066,8 +1066,8 @@ EOF;
$action = sprintf(__('Deleted %s'),'>>' . $post['id']) . ' - ' . hashData($post['ip']);
$stripped = strip_tags($post['message']);
if ($stripped != '') {
- $action .= ' - ' . htmlentities(substr($stripped, 0, 32));
- if (strlen($stripped) > 32) {
+ $action .= ' - ' . htmlentities(_substr($stripped, 0, 32));
+ if (_strlen($stripped) > 32) {
$action .= '...';
}
}
diff --git a/inc/functions.php b/inc/functions.php
index 8c760a6..649269f 100644
--- a/inc/functions.php
+++ b/inc/functions.php
@@ -3,6 +3,8 @@ if (!defined('TINYIB_BOARD')) {
die('');
}
+$multibyte_enabled = function_exists('mb_strlen');
+
if (!function_exists('array_column')) {
function array_column($array, $column_name) {
return array_map(function ($element) use ($column_name) {
@@ -24,6 +26,38 @@ function lockDatabase() {
return $fp;
}
+function _strlen($string) {
+ global $multibyte_enabled;
+ if ($multibyte_enabled) {
+ return mb_strlen($string);
+ }
+ return strlen($string);
+}
+
+function _strpos($haystack, $needle, $offset=0) {
+ global $multibyte_enabled;
+ if ($multibyte_enabled) {
+ return mb_strpos($haystack, $needle, $offset);
+ }
+ return strpos($haystack, $needle, $offset);
+}
+
+function _substr($string, $start, $length=null) {
+ global $multibyte_enabled;
+ if ($multibyte_enabled) {
+ return mb_substr($string, $start, $length);
+ }
+ return substr($string, $start, $length);
+}
+
+function _substr_count($haystack, $needle) {
+ global $multibyte_enabled;
+ if ($multibyte_enabled) {
+ return mb_substr_count($haystack, $needle);
+ }
+ return substr_count($haystack, $needle);
+}
+
function hashData($data, $force = false) {
global $bcrypt_salt;
if (substr($data, 0, 4) == '$2y$' && !$force) {
@@ -388,8 +422,8 @@ function checkFlood() {
}
function checkMessageSize() {
- if (TINYIB_MAXMESSAGE > 0 && strlen($_POST['message']) > TINYIB_MAXMESSAGE) {
- fancyDie(sprintf(__('Please shorten your message, or post it in multiple parts. Your message is %1$d characters long, and the maximum allowed is %2$d.'), strlen($_POST['message']), TINYIB_MAXMESSAGE));
+ if (TINYIB_MAXMESSAGE > 0 && _strlen($_POST['message']) > TINYIB_MAXMESSAGE) {
+ fancyDie(sprintf(__('Please shorten your message, or post it in multiple parts. Your message is %1$d characters long, and the maximum allowed is %2$d.'), _strlen($_POST['message']), TINYIB_MAXMESSAGE));
}
}
@@ -793,8 +827,8 @@ function addVideoOverlay($thumb_location) {
function strallpos($haystack, $needle, $offset = 0) {
$result = array();
- for ($i = $offset; $i < strlen($haystack); $i++) {
- $pos = strpos($haystack, $needle, $i);
+ for ($i = $offset; $i < _strlen($haystack); $i++) {
+ $pos = _strpos($haystack, $needle, $i);
if ($pos !== False) {
$offset = $pos;
if ($offset >= $i) {
@@ -900,7 +934,7 @@ function attachFile($post, $filepath, $filename, $uploaded, $spoiler) {
}
$post['file'] = $file_name;
- $post['file_original'] = trim(htmlentities(substr($filename, 0, 50), ENT_QUOTES));
+ $post['file_original'] = trim(htmlentities(_substr($filename, 0, 50), ENT_QUOTES));
$post['file_hex'] = md5_file($filepath);
$post['file_size'] = $filesize;
$post['file_size_formatted'] = convertBytes($post['file_size']);
diff --git a/inc/html.php b/inc/html.php
index 17c9ed4..7aad9af 100644
--- a/inc/html.php
+++ b/inc/html.php
@@ -594,9 +594,9 @@ EOF;
$return .= backlinks($post);
}
- if (TINYIB_TRUNCATE > 0 && !$res && substr_count($post['message'], '
') > TINYIB_TRUNCATE) { // Truncate messages on board index pages for readability
+ if (TINYIB_TRUNCATE > 0 && !$res && _substr_count($post['message'], '
') > TINYIB_TRUNCATE) { // Truncate messages on board index pages for readability
$br_offsets = strallpos($post['message'], '
');
- $post['message'] = substr($post['message'], 0, $br_offsets[TINYIB_TRUNCATE - 1]);
+ $post['message'] = _substr($post['message'], 0, $br_offsets[TINYIB_TRUNCATE - 1]);
$post['message'] .= '
' . __('Post truncated. Click Reply to view.') . '
';
}
$return .= <<