diff --git a/include/conversation.php b/include/conversation.php
index 5b7ccbd8a1..0eb94181f0 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -376,17 +376,17 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
. "\r\n";
}
diff --git a/mod/network.php b/mod/network.php
index 1506c70737..433d4079c1 100644
--- a/mod/network.php
+++ b/mod/network.php
@@ -58,8 +58,8 @@ function network_init(App $a)
$group_id = (($a->argc > 1 && is_numeric($a->argv[1])) ? intval($a->argv[1]) : 0);
$cid = 0;
- if (!empty($_GET['cid'])) {
- $cid = $_GET['cid'];
+ if (!empty($_GET['contactid'])) {
+ $cid = $_GET['contactid'];
$_GET['nets'] = '';
$group_id = 0;
}
@@ -466,12 +466,12 @@ function networkThreadedView(App $a, $update, $parent)
$o = '';
- $cid = intval($_GET['cid'] ?? 0);
- $star = intval($_GET['star'] ?? 0);
- $bmark = intval($_GET['bmark'] ?? 0);
- $conv = intval($_GET['conv'] ?? 0);
+ $cid = intval($_GET['contactid'] ?? 0);
+ $star = intval($_GET['star'] ?? 0);
+ $bmark = intval($_GET['bmark'] ?? 0);
+ $conv = intval($_GET['conv'] ?? 0);
$order = Strings::escapeTags(($_GET['order'] ?? '') ?: 'activity');
- $nets = $_GET['nets'] ?? '';
+ $nets = $_GET['nets'] ?? '';
$allowedCids = [];
if ($cid) {
@@ -786,6 +786,13 @@ function networkThreadedView(App $a, $update, $parent)
$top_limit = DateTimeFormat::utcNow();
}
+ // Handle bad performance situations when the distance between top and bottom is too high
+ // See issue https://github.com/friendica/friendica/issues/8619
+ if (strtotime($top_limit) - strtotime($bottom_limit) > 86400) {
+ // Set the bottom limit to one day in the past at maximum
+ $bottom_limit = DateTimeFormat::utc(date('c', strtotime($top_limit) - 86400));
+ }
+
$items = DBA::p("SELECT `item`.`parent-uri` AS `uri`, 0 AS `item_id`, `item`.$ordering AS `order_date`, `author`.`url` AS `author-link` FROM `item`
STRAIGHT_JOIN (SELECT `uri-id` FROM `tag-search-view` WHERE `name` IN
(SELECT SUBSTR(`term`, 2) FROM `search` WHERE `uid` = ? AND `term` LIKE '#%') AND `uid` = 0) AS `tag-search`
@@ -891,8 +898,8 @@ function network_tabs(App $a)
$cmd = DI::args()->getCommand();
$def_param = [];
- if (!empty($_GET['cid'])) {
- $def_param['cid'] = $_GET['cid'];
+ if (!empty($_GET['contactid'])) {
+ $def_param['contactid'] = $_GET['contactid'];
}
// tabs
diff --git a/src/Content/ForumManager.php b/src/Content/ForumManager.php
index 7d3cb89a71..9441e9dbb0 100644
--- a/src/Content/ForumManager.php
+++ b/src/Content/ForumManager.php
@@ -126,7 +126,7 @@ class ForumManager
$selected = (($cid == $contact['id']) ? ' forum-selected' : '');
$entry = [
- 'url' => 'network?cid=' . $contact['id'],
+ 'url' => 'network?contactid=' . $contact['id'],
'external_url' => Contact::magicLink($contact['url']),
'name' => $contact['name'],
'cid' => $contact['id'],
diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php
index 98c1552930..67dbe3b19a 100644
--- a/src/Content/Text/BBCode.php
+++ b/src/Content/Text/BBCode.php
@@ -1724,7 +1724,15 @@ class BBCode
// Replace non graphical smilies for external posts
if (!$nosmile && !$for_plaintext) {
- $text = Smilies::replace($text);
+ $text = Smilies::replace($text);
+ }
+
+ if (!$for_plaintext && DI::config()->get('system', 'big_emojis') && ($simple_html != self::DIASPORA)) {
+ $conv = html_entity_decode(str_replace([' ', "\n", "\r"], '', $text));
+ // Emojis are always 4 byte Unicode characters
+ if (!empty($conv) && (strlen($conv) / mb_strlen($conv) == 4)) {
+ $text = '' . $text . '';
+ }
}
if (!$for_plaintext) {
diff --git a/src/Database/Database.php b/src/Database/Database.php
index 7adb88ffa8..05ce3693b4 100644
--- a/src/Database/Database.php
+++ b/src/Database/Database.php
@@ -135,8 +135,9 @@ class Database
}
$this->emulate_prepares = (bool)$this->configCache->get('database', 'emulate_prepares');
+ $this->pdo_emulate_prepares = (bool)$this->configCache->get('database', 'pdo_emulate_prepares');
- if (class_exists('\PDO') && in_array('mysql', PDO::getAvailableDrivers())) {
+ if (!$this->configCache->get('database', 'disable_pdo') && class_exists('\PDO') && in_array('mysql', PDO::getAvailableDrivers())) {
$this->driver = 'pdo';
$connect = "mysql:host=" . $server . ";dbname=" . $db;
@@ -150,7 +151,7 @@ class Database
try {
$this->connection = @new PDO($connect, $user, $pass);
- $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
+ $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, $this->pdo_emulate_prepares);
$this->connected = true;
} catch (PDOException $e) {
$this->connected = false;
@@ -504,6 +505,7 @@ class Database
$sql = "/*" . System::callstack() . " */ " . $sql;
}
+ $is_error = false;
$this->error = '';
$this->errorno = 0;
$this->affected_rows = 0;
@@ -533,6 +535,7 @@ class Database
$this->error = $errorInfo[2];
$this->errorno = $errorInfo[1];
$retval = false;
+ $is_error = true;
break;
}
$this->affected_rows = $retval->rowCount();
@@ -545,6 +548,7 @@ class Database
$this->error = $errorInfo[2];
$this->errorno = $errorInfo[1];
$retval = false;
+ $is_error = true;
break;
}
@@ -562,6 +566,7 @@ class Database
$this->error = $errorInfo[2];
$this->errorno = $errorInfo[1];
$retval = false;
+ $is_error = true;
} else {
$retval = $stmt;
$this->affected_rows = $retval->rowCount();
@@ -580,6 +585,7 @@ class Database
$this->error = $this->connection->error;
$this->errorno = $this->connection->errno;
$retval = false;
+ $is_error = true;
} else {
if (isset($retval->num_rows)) {
$this->affected_rows = $retval->num_rows;
@@ -596,6 +602,7 @@ class Database
$this->error = $stmt->error;
$this->errorno = $stmt->errno;
$retval = false;
+ $is_error = true;
break;
}
@@ -623,6 +630,7 @@ class Database
$this->error = $this->connection->error;
$this->errorno = $this->connection->errno;
$retval = false;
+ $is_error = true;
} else {
$stmt->store_result();
$retval = $stmt;
@@ -631,6 +639,16 @@ class Database
break;
}
+ // See issue https://github.com/friendica/friendica/issues/8572
+ // Ensure that we always get an error message on an error.
+ if ($is_error && empty($this->errorno)) {
+ $this->errorno = -1;
+ }
+
+ if ($is_error && empty($this->error)) {
+ $this->error = 'Unknown database error';
+ }
+
// We are having an own error logging in the function "e"
if (($this->errorno != 0) && !$called_from_e) {
// We have to preserve the error code, somewhere in the logging it get lost
@@ -642,8 +660,8 @@ class Database
}
$this->logger->error('DB Error', [
- 'code' => $this->errorno,
- 'error' => $this->error,
+ 'code' => $errorno,
+ 'error' => $error,
'callstack' => System::callstack(8),
'params' => $this->replaceParameters($sql, $args),
]);
@@ -654,21 +672,21 @@ class Database
// It doesn't make sense to continue when the database connection was lost
if ($this->in_retrial) {
$this->logger->notice('Giving up retrial because of database error', [
- 'code' => $this->errorno,
- 'error' => $this->error,
+ 'code' => $errorno,
+ 'error' => $error,
]);
} else {
$this->logger->notice('Couldn\'t reconnect after database error', [
- 'code' => $this->errorno,
- 'error' => $this->error,
+ 'code' => $errorno,
+ 'error' => $error,
]);
}
exit(1);
} else {
// We try it again
$this->logger->notice('Reconnected after database error', [
- 'code' => $this->errorno,
- 'error' => $this->error,
+ 'code' => $errorno,
+ 'error' => $error,
]);
$this->in_retrial = true;
$ret = $this->p($sql, $args);
@@ -745,8 +763,8 @@ class Database
}
$this->logger->error('DB Error', [
- 'code' => $this->errorno,
- 'error' => $this->error,
+ 'code' => $errorno,
+ 'error' => $error,
'callstack' => System::callstack(8),
'params' => $this->replaceParameters($sql, $params),
]);
@@ -755,8 +773,8 @@ class Database
// A reconnect like in $this->p could be dangerous with modifications
if ($errorno == 2006) {
$this->logger->notice('Giving up because of database error', [
- 'code' => $this->errorno,
- 'error' => $this->error,
+ 'code' => $errorno,
+ 'error' => $error,
]);
exit(1);
}
@@ -1029,7 +1047,7 @@ class Database
$success = $this->e("LOCK TABLES " . DBA::buildTableString($table) . " WRITE");
if ($this->driver == 'pdo') {
- $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
+ $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, $this->pdo_emulate_prepares);
}
if (!$success) {
@@ -1062,7 +1080,7 @@ class Database
$success = $this->e("UNLOCK TABLES");
if ($this->driver == 'pdo') {
- $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
+ $this->connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, $this->pdo_emulate_prepares);
$this->e("SET autocommit=1");
} else {
$this->connection->autocommit(true);
diff --git a/src/Model/GServer.php b/src/Model/GServer.php
index bc189af9d6..f750ed99ea 100644
--- a/src/Model/GServer.php
+++ b/src/Model/GServer.php
@@ -353,6 +353,15 @@ class GServer
return;
}
+ // Sanitize incoming data, see https://github.com/friendica/friendica/issues/8565
+ $data['subscribe'] = (bool)$data['subscribe'] ?? false;
+
+ if (!$data['subscribe'] || empty($data['scope']) || !in_array(strtolower($data['scope']), ['all', 'tags'])) {
+ $data['scope'] = '';
+ $data['subscribe'] = false;
+ $data['tags'] = [];
+ }
+
$gserver = DBA::selectFirst('gserver', ['id', 'relay-subscribe', 'relay-scope'], ['nurl' => Strings::normaliseLink($server_url)]);
if (!DBA::isResult($gserver)) {
return;
diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php
index dd1f678d58..243550862b 100644
--- a/src/Protocol/Diaspora.php
+++ b/src/Protocol/Diaspora.php
@@ -3139,7 +3139,9 @@ class Diaspora
$json = json_encode(["iv" => $b_iv, "key" => $b_aes_key]);
$encrypted_key_bundle = "";
- openssl_public_encrypt($json, $encrypted_key_bundle, $pubkey);
+ if (!@openssl_public_encrypt($json, $encrypted_key_bundle, $pubkey)) {
+ return false;
+ }
$json_object = json_encode(
["aes_key" => base64_encode($encrypted_key_bundle),
diff --git a/static/defaults.config.php b/static/defaults.config.php
index d0725aa9bc..a1d50bb84f 100644
--- a/static/defaults.config.php
+++ b/static/defaults.config.php
@@ -45,8 +45,23 @@ return [
'database' => '',
// charset (String)
- // Database connexion charset. Changing this value will likely corrupt special characters.
+ // Database connection charset. Changing this value will likely corrupt special characters.
'charset' => 'utf8mb4',
+
+ // emulate_prepares (Boolean) (Experimental)
+ // If enabled, prepared statements will be emulated.
+ // In combination with MySQLi this will cast all return values to strings.
+ 'emulate_prepares' => false,
+
+ // pdo_emulate_prepares (Boolean) (Experimental)
+ // If enabled, the builtin emulation for prepared statements is used.
+ // Due to limitations of that emulation (all return values are casted as strings)
+ // this will most likely cause issues and should not be used on production systems.
+ 'pdo_emulate_prepares' => false,
+
+ // disable_pdo (Boolean)
+ // PDO is used by default (if available). Otherwise MySQLi will be used.
+ 'disable_pdo' => false,
],
'config' => [
// admin_email (Comma-separated list)
@@ -88,6 +103,10 @@ return [
// chose "Remember me" when logging in is considered logged out.
'auth_cookie_lifetime' => 7,
+ // big_emojis (Boolean)
+ // Display "Emoji Only" posts in big.
+ 'big_emojis' => false,
+
// block_local_dir (Boolean)
// Deny public access to the local user directory.
'block_local_dir' => false,
diff --git a/tests/Util/Database/StaticDatabase.php b/tests/Util/Database/StaticDatabase.php
index f2ed6c700e..c95b690c63 100644
--- a/tests/Util/Database/StaticDatabase.php
+++ b/tests/Util/Database/StaticDatabase.php
@@ -56,6 +56,8 @@ class StaticDatabase extends Database
$this->driver = 'pdo';
$this->connection = self::$staticConnection;
$this->connected = true;
+ $this->emulate_prepares = false;
+ $this->pdo_emulate_prepares = false;
return $this->connected;
}
diff --git a/tests/src/Content/Text/BBCodeTest.php b/tests/src/Content/Text/BBCodeTest.php
index 1a1d06dc7b..35dff87d9f 100644
--- a/tests/src/Content/Text/BBCodeTest.php
+++ b/tests/src/Content/Text/BBCodeTest.php
@@ -58,6 +58,9 @@ class BBCodeTest extends MockedTest
$this->configMock->shouldReceive('get')
->with('system', 'no_smilies')
->andReturn(false);
+ $this->configMock->shouldReceive('get')
+ ->with('system', 'big_emojis')
+ ->andReturn(false);
$l10nMock = \Mockery::mock(L10n::class);
$l10nMock->shouldReceive('t')->withAnyArgs()->andReturnUsing(function ($args) { return $args; });
diff --git a/view/theme/vier/theme.php b/view/theme/vier/theme.php
index cc3a668e6a..cec5e5ba63 100644
--- a/view/theme/vier/theme.php
+++ b/view/theme/vier/theme.php
@@ -202,7 +202,7 @@ function vier_community_info()
$selected = (($cid == $contact['id']) ? ' forum-selected' : '');
$entry = [
- 'url' => 'network?cid=' . $contact['id'],
+ 'url' => 'network?contactid=' . $contact['id'],
'external_url' => Contact::magicLink($contact['url']),
'name' => $contact['name'],
'cid' => $contact['id'],