Merge branch 'dev' into release

This commit is contained in:
Mike Macgirvin 2022-06-25 17:17:47 -07:00
commit 7b4d45d6a2
22 changed files with 98 additions and 95 deletions

View file

@ -3759,9 +3759,10 @@ class Activity
// provided by either of these entities.
$abook = q(
"select * from abook where ( abook_xchan = '%s' OR abook_xchan = '%s') and abook_channel = %d ",
"select * from abook where ( abook_xchan = '%s' OR abook_xchan = '%s' OR abook_xchan = '%s') and abook_channel = %d ",
dbesc($item['author_xchan']),
dbesc($item['owner_xchan']),
dbesc($observer_hash),
intval($channel['channel_id'])
);
@ -4014,12 +4015,6 @@ class Activity
break;
}
if (count($p) > 100) {
logger('Conversation overflow');
$p = [];
break;
}
array_unshift($p, [$a, $item]);
if ($item['parent_mid'] === $item['mid']) {

View file

@ -6,6 +6,7 @@ use Code\Extend\Hook;
class DReport
{
const EXPIRE_DAYS = 10;
private $location;
private $sender;
@ -66,6 +67,16 @@ class DReport
);
}
public static function is_expired($item, $expire_days = 0) {
if ($expire_days === 0) {
$expire_days = self::EXPIRE_DAYS;
}
if (strcmp(datetime_convert(datetime: $item['created']), datetime_convert(datetime: "now - $expire_days days")) > 0) {
return false;
}
return true;
}
/**
* @brief decide whether to store a returned delivery report
*

View file

@ -1980,10 +1980,11 @@ class Libzot
// This is used to fetch allow/deny rules if either the sender
// or owner is a connection. post_is_importable() evaluates all of them
$abook = q(
"select * from abook where abook_channel = %d and ( abook_xchan = '%s' OR abook_xchan = '%s' )",
"select * from abook where abook_channel = %d and ( abook_xchan = '%s' OR abook_xchan = '%s' OR abook_xchan = '%s')",
intval($channel['channel_id']),
dbesc($arr['owner_xchan']),
dbesc($arr['author_xchan'])
dbesc($arr['author_xchan']),
dbesc($sender)
);
if (isset($arr['item_deleted']) && intval($arr['item_deleted'])) {

View file

@ -40,10 +40,7 @@ class Attach extends Controller
header('Content-Disposition: attachment; filename="' . $r['data']['filename'] . '"');
if (intval($r['data']['os_storage'])) {
$fname = dbunescbin($r['data']['content']);
Stdio::fpipe((strpos($fname, 'store') !== false)
? $fname
: 'store/' . $channel['channel_address'] . '/' . $fname,
'php://output');
Stdio::fcopy($fname, 'php://output');
} else {
echo dbunescbin($r['data']['content']);
}

View file

@ -48,7 +48,7 @@ class Ca extends Controller
. '; max-age=' . $cache . ';'
);
Stdio::fpipe($path,'php://output');
Stdio::fcopy($path,'php://output');
killme();
}

View file

@ -827,7 +827,7 @@ class Events extends Controller
drop_item($i[0]['id']);
} else {
// complex deletion that needs to propagate and be performed in phases
drop_item($i[0]['id'], true, DROPITEM_PHASE1);
drop_item($i[0]['id'], false, DROPITEM_PHASE1);
$complex = true;
}
@ -843,6 +843,9 @@ class Events extends Controller
if ($complex) {
tag_deliver($i[0]['uid'], $i[0]['id']);
if (intval($i[0]['item_wall']) && $complex) {
Run::Summon(['Notifier', 'drop', $i[0]['id']]);
}
}
}
}

View file

@ -95,11 +95,7 @@ class Getfile extends Controller
header('Content-type: ' . $r[0]['mimetype']);
if (intval($r[0]['os_storage'])) {
$fname = dbunescbin($r[0]['content']);
Stdio::fpipe((strpos($fname, 'store') !== false)
? $fname
: 'store/' . $channel['channel_address'] . '/' . $fname,
'php://output');
Stdio::fcopy(dbunescbin($r[0]['content']), 'php://output');
} else {
echo dbunescbin($r[0]['content']);
}
@ -118,11 +114,7 @@ class Getfile extends Controller
header('Content-type: ' . $r['data']['filetype']);
header('Content-Disposition: attachment; filename="' . $r['data']['filename'] . '"');
if (intval($r['data']['os_storage'])) {
$fname = dbunescbin($r['data']['content']);
Stdio::fpipe((strpos($fname, 'store') !== false)
? $fname
: 'store/' . $channel['channel_address'] . '/' . $fname,
'php://output');
Stdio::fcopy(dbunescbin($r['data']['content']),'php://output');
} else {
echo dbunescbin($r['data']['content']);
}

View file

@ -1873,6 +1873,9 @@ class Item extends Controller
if ($complex) {
tag_deliver($i[0]['uid'], $i[0]['id']);
if (intval($i[0]['item_wall']) && $complex) {
Run::Summon(['Notifier', 'drop', $i[0]['id']]);
}
}
}
}

View file

@ -307,10 +307,7 @@ class Photo extends Controller
// If it's a file resource, stream it.
if ($streaming && $channel) {
Stdio::fpipe((strpos($streaming, 'store') !== false)
? $streaming
: 'store/' . $channel['channel_address'] . '/' . $streaming,
'php://output');
Stdio::fcopy($streaming, 'php://output');
} else {
echo $data;
}

View file

@ -52,7 +52,7 @@ class Xp extends Controller
$smaxage = intval($cache / 12);
header('Cache-Control: s-maxage=' . $smaxage . '; max-age=' . $cache . ';');
Stdio::fpipe($path,'php://output');
Stdio::fcopy($path,'php://output');
killme();
}

View file

@ -192,14 +192,7 @@ class File extends DAV\Node implements DAV\IFile {
$direct = $f1[0];
}
}
$fname = dbunescbin($d[0]['content']);
if (strpos($fname,'store/') === false) {
$f = 'store/' . $this->auth->owner_nick . '/' . $fname ;
}
else {
$f = $fname;
}
$f = dbunescbin($d[0]['content']);
if (is_resource($data)) {
$fp = fopen($f,'wb');
if ($fp) {

View file

@ -7,13 +7,16 @@ use Exception;
Class Stdio {
static public function mkdir($path, $mode = 0777, $recursive = false) {
$result = false;
try {
$oldumask = umask(0);
$result = mkdir($path, $mode, $recursive);
umask($oldumask);
} catch (Exception $e) {
} catch (\Exception $e) {
// null operation
} finally {
umask($oldumask);
}
return $result;
}
@ -23,11 +26,11 @@ Class Stdio {
*
* @return int bytes written | false
*/
static public function fpipe($infile, $outfile, $bufsize = 65535, $filemode = 'wb')
static public function fcopy($infile, $outfile, $bufsize = 65535, $read_mode = 'rb', $write_mode = 'wb')
{
$size = 0;
$in = fopen($infile, 'rb');
$out = fopen($outfile, $filemode);
$size = false;
$in = fopen($infile, $read_mode);
$out = fopen($outfile, $write_mode);
if ($in && $out) {
$size = self::pipe_streams($in, $out, $bufsize);
}

View file

@ -21,7 +21,7 @@ class Pdf
$tmpfile = $file . '.pdf';
$outfile = $file . '.jpg';
Stdio::fpipe($file,$tmpfile);
Stdio::fcopy($file,$tmpfile);
$imagick_path = get_config('system', 'imagick_convert_path');
if ($imagick_path && @file_exists($imagick_path)) {

View file

@ -29,7 +29,7 @@ class Video
$tmpfile = $file . $extension;
$outfile = $file . '.jpg';
Stdio::fpipe($file,$tmpfile);
Stdio::fcopy($file,$tmpfile);
/*
* Note: imagick convert may try to call 'ffmpeg' (or other conversion utilities) under

View file

@ -18,6 +18,6 @@ Guest Pass: Provide special guest access to private resources and media - on you
Friend Zoom: Set your degree of closeness to any connection and then interactively zoom in to filter your stream to close friends; or zoom out to see posts by casual acquaintances.
Delivery Reports: Allows you to determine what happened to your post or comment and where it actually went once you published it.
Delivery Reports: In a decentralised multi-platform world, stuff happens. Sites and networks sometimes go down. Project developers sometimes introduce bugs and incompatibilities. This allows you to determine what happened to your post or comment and where it actually went once you published it.
Failsafe: Because the best time to have a current backup of your data is 10 seconds ago. Clone your online identity and content to multiple sites using the Nomad protocol and mirror any changes in near realtime. Then if your chosen site goes down (either temporarily or permanently) or you get booted off of it for some reason, your online life doesn't have to come to an end or force you to start over. All your friends and all your content are available on any of your cloned instances - at any time.

View file

@ -2498,28 +2498,28 @@ function cert_bad_email() {
*/
function check_cron_broken() {
$d = get_config('system','lastcron');
$d = get_config('system', 'lastcron');
if((! $d) || ($d < datetime_convert('UTC','UTC','now - 4 hours'))) {
if((! $d) || ($d < datetime_convert(datetime: 'now - 4 hours'))) {
Run::Summon( [ 'Cron' ] );
set_config('system','lastcron',datetime_convert());
set_config('system', 'lastcron', datetime_convert());
}
$t = get_config('system','lastcroncheck');
$t = get_config('system', 'lastcroncheck');
if(! $t) {
// never checked before. Start the timer.
set_config('system','lastcroncheck',datetime_convert());
set_config('system', 'lastcroncheck', datetime_convert());
return true;
}
if($t > datetime_convert('UTC','UTC','now - 3 days')) {
if($t > datetime_convert(datetime: 'now - 3 days')) {
// Wait for 3 days before we do anything so as not to swamp the admin with messages
return true;
}
set_config('system','lastcroncheck',datetime_convert());
set_config('system', 'lastcroncheck', datetime_convert());
if(($d) && ($d > datetime_convert('UTC','UTC','now - 3 days'))) {
if(($d) && ($d > datetime_convert(datetime: 'now - 3 days'))) {
// Scheduled tasks have run successfully in the last 3 days.
return true;
}

View file

@ -872,7 +872,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null)
$display_path = ltrim($pathname . '/' . $filename, '/');
if ($src) {
Stdio::fpipe($src, $os_basepath . $os_relpath);
Stdio::fcopy($src, $os_basepath . $os_relpath);
}
if (array_key_exists('created', $arr)) {
@ -1603,13 +1603,7 @@ function attach_delete($channel_id, $resource, $is_photo = 0)
);
if ($y) {
$y[0]['content'] = dbunescbin($y[0]['content']);
if (strpos($y[0]['content'], 'store') === false) {
$f = 'store/' . $channel_address . '/' . $y[0]['content'];
} else {
$f = $y[0]['content'];
}
$f = dbunescbin($y[0]['content']);
if (is_dir($f)) {
@rmdir($f);
} elseif (file_exists($f)) {
@ -2808,7 +2802,7 @@ function save_chunk($channel, $start, $end, $len)
if (! file_exists($new_path)) {
rename($tmp_path, $new_path);
} else {
Stdio::fpipe($tmp_path, $new_path, 65535, 'ab');
Stdio::fcopy($tmp_path, $new_path, write_mode: 'ab');
}
if (($len - 1) == $end) {
unlink($tmp_path);

View file

@ -664,7 +664,7 @@ function bb_ShareAttributes($match)
$reldate = '<span class="autotime" title="' . datetime_convert('UTC', date_default_timezone_get(), $posted, 'c') . '" >' . datetime_convert('UTC', date_default_timezone_get(), $posted, 'r') . '</span>';
$headline = '<div class="shared_container"> <div class="shared_header">';
$headline = '<article><div class="shared_container"> <div class="shared_header">';
if ($avatar != "") {
$headline .= '<a href="' . (($auth) ? zid($profile) : $profile) . '" ><img src="' . $avatar . '" alt="' . htmlspecialchars($author, ENT_COMPAT, 'UTF-8', false) . '" height="32" width="32" loading="lazy" /></a>';
@ -689,7 +689,7 @@ function bb_ShareAttributes($match)
$headline .= '<span>' . $fmt . '</span></div>';
$text = $headline . '<div class="reshared-content">' . trim($match[2]) . '</div></div>';
$text = $headline . '<div class="reshared-content">' . trim($match[2]) . '</div></div></article>';
return $text;
}

View file

@ -92,12 +92,12 @@ function get_timezones()
*
* @param string $from source timezone
* @param string $to dest timezone
* @param string $s some parseable date/time string
* @param string $fmt output format recognised from php's DateTime class
* @param string $datetime some parseable date/time string
* @param string $format output format recognised from php's DateTime class
* http://www.php.net/manual/en/datetime.format.php
* @return string
*/
function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d H:i:s")
function datetime_convert($from = 'UTC', $to = 'UTC', $datetime = 'now', $format = "Y-m-d H:i:s")
{
// Defaults to UTC if nothing is set, but throws an exception if set to empty string.
@ -109,13 +109,13 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d
if ($to === '') {
$to = 'UTC';
}
if (($s === '') || (! is_string($s))) {
$s = 'now';
if (($datetime === '') || (! is_string($datetime))) {
$datetime = 'now';
}
if (is_null_date($s)) {
if (is_null_date($datetime)) {
$d = new DateTime('0001-01-01 00:00:00', new DateTimeZone('UTC'));
return $d->format($fmt);
return $d->format($format);
}
try {
@ -125,7 +125,7 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d
}
try {
$d = new DateTime($s, $from_obj);
$d = new DateTime($datetime, $from_obj);
} catch (Exception $e) {
logger('exception: ' . $e->getMessage());
$d = new DateTime('now', $from_obj);
@ -139,7 +139,7 @@ function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d
$d->setTimeZone($to_obj);
return($d->format($fmt));
return($d->format($format));
}
/**
@ -403,10 +403,7 @@ function age($dob, $owner_tz = '', $viewer_tz = '')
*/
function get_dim($y, $m)
{
$dim = array( 0,
31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31
);
$dim = [ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
if ($m != 2) {
return $dim[$m];

View file

@ -3426,23 +3426,23 @@ function check_item_source($uid, $item) {
// Checks an incoming item against the per-channel and per-connection content filter.
// This implements the backend of the 'Content Filter' system app
function post_is_importable($channel_id,$item,$abook) {
function post_is_importable($channel_id, $item, $abook) {
if (! $item) {
return false;
}
if (! Apps::system_app_installed($channel_id,'Content Filter')) {
if (! Apps::system_app_installed($channel_id, 'Content Filter')) {
return true;
}
$incl = PConfig::get($channel_id,'system','message_filter_incl',EMPTY_STR);
$excl = PConfig::get($channel_id,'system','message_filter_excl',EMPTY_STR);
$incl = PConfig::get($channel_id, 'system', 'message_filter_incl', EMPTY_STR);
$excl = PConfig::get($channel_id, 'system', 'message_filter_excl', EMPTY_STR);
if ($incl || $excl) {
$x = MessageFilter::evaluate($item,$incl,$excl);
$x = MessageFilter::evaluate($item, $incl, $excl);
if (! $x) {
logger('MessageFilter: channel blocked content',LOGGER_DEBUG,LOG_INFO);
logger('MessageFilter: channel blocked content', LOGGER_DEBUG, LOG_INFO);
return false;
}
}
@ -3460,9 +3460,8 @@ function post_is_importable($channel_id,$item,$abook) {
if (! ($ab['abook_incl'] || $ab['abook_excl']) ) {
continue;
}
$evaluator = MessageFilter::evaluate($item,$ab['abook_incl'],$ab['abook_excl']);
// A negative assessment for any individual connections
// is an instant fail
$evaluator = MessageFilter::evaluate($item, $ab['abook_incl'], $ab['abook_excl']);
// A negative assessment for any individual connections is an instant fail.
if (! $evaluator) {
return false;
}
@ -3694,6 +3693,9 @@ function drop_items($items,$interactive = false,$stage = DROPITEM_NORMAL,$force
// $stage = 1 => set deleted flag on the item and perform intial notifications
// $stage = 2 => perform low level delete at a later stage
// @FIXME: interactive mode is deprecated and should no longer be used.
// It should be removed however doing this will require significant testing.
function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL,$force = false) {
// These resource types have linked items that should only be removed at the same time

View file

@ -1792,18 +1792,33 @@ function generate_named_map($location)
return (($arr['html']) ? $arr['html'] : $location);
}
function item_is_censored($item, $observer) {
// Don't censor your own posts.
if ($observer && $item['author_xchan'] === $observer) {
return false;
}
$censored = ((($item['author']['abook_censor']
|| $item['owner']['abook_censor']
|| $item['author']['xchan_selfcensored']
|| $item['owner']['xchan_selfcensored']
|| $item['author']['xchan_censored']
|| $item['owner']['xchan_censored']
|| intval($item['item_nsfw'])) && (get_safemode()))
? true
: false
);
return $censored;
}
function prepare_body(&$item, $attach = false, $opts = false)
{
Hook::call('prepare_body_init', $item);
$censored = ((($item['author']['abook_censor'] || $item['owner']['abook_censor'] || $item['author']['xchan_selfcensored'] || $item['owner']['xchan_selfcensored'] || $item['author']['xchan_censored'] || $item['owner']['xchan_censored'] || intval($item['item_nsfw'])) && (get_safemode()))
? true
: false
);
if ($censored) {
if (item_is_censored($item, get_observer_hash())) {
if (! $opts) {
$opts = [];
}

View file

@ -1,2 +1,2 @@
<?php
define ( 'STD_VERSION', '22.06.24' );
define ( 'STD_VERSION', '22.06.26' );