From 08941d42856984a3076e972804ac016400341f91 Mon Sep 17 00:00:00 2001 From: friendica Date: Sat, 26 May 2012 23:46:42 -0700 Subject: [PATCH 1/5] handle multiple underscores in D* links --- include/auth.php | 2 ++ include/bb2diaspora.php | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/auth.php b/include/auth.php index b87662fea..cba6a67a7 100644 --- a/include/auth.php +++ b/include/auth.php @@ -53,6 +53,8 @@ if((isset($_SESSION)) && (x($_SESSION,'authenticated')) && ((! (x($_POST,'auth-p $check = get_config('system','paranoia'); // extra paranoia - if the IP changed, log them out if($check && ($_SESSION['addr'] != $_SERVER['REMOTE_ADDR'])) { + logger('Session address changed. Paranoid setting in effect, blocking session. ' + . $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']); nuke_session(); goaway(z_root()); } diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php index 8487f845a..d86ba4543 100644 --- a/include/bb2diaspora.php +++ b/include/bb2diaspora.php @@ -221,13 +221,18 @@ function bb2diaspora($Text,$preserve_nl = false) { $Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism",'<$1$2=$3&$4>',$Text); - $Text = preg_replace('/\[(.*?)\]\((.*?)\\\\_(.*?)\)/ism','[$1]($2_$3)',$Text); + $Text = preg_replace_callback('/\[(.*?)\]\((.*?)\)/ism','unescape_underscores_in_links',$Text); call_hooks('bb2diaspora',$Text); return $Text; } +function unescape_underscores_in_links($m) { + $y = str_replace('\\_','_', $m[2]); + return('[' . $m[1] . '](' . $y . ')'); +} + function format_event_diaspora($ev) { $a = get_app(); From 2bd1004587fc8d928b9458b2383b656df115578c Mon Sep 17 00:00:00 2001 From: friendica Date: Sun, 27 May 2012 21:01:58 -0700 Subject: [PATCH 2/5] rework the way private photos are embedded to avoid url differences and also check the permissions if possible to make sure that nothing sneaks by. --- boot.php | 2 +- include/delivery.php | 2 +- include/items.php | 88 +++++++++++++++++++++++++++++--- include/notifier.php | 2 +- mod/settings.php | 1 + util/messages.po | 116 +++++++++++++++++++++---------------------- 6 files changed, 142 insertions(+), 69 deletions(-) diff --git a/boot.php b/boot.php index b41b8d9a0..aff026a71 100644 --- a/boot.php +++ b/boot.php @@ -9,7 +9,7 @@ require_once('include/nav.php'); require_once('include/cache.php'); define ( 'FRIENDICA_PLATFORM', 'Friendica'); -define ( 'FRIENDICA_VERSION', '3.0.1355' ); +define ( 'FRIENDICA_VERSION', '3.0.1356' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); define ( 'DB_UPDATE_VERSION', 1144 ); diff --git a/include/delivery.php b/include/delivery.php index 61b0bd33a..32943d5da 100644 --- a/include/delivery.php +++ b/include/delivery.php @@ -288,7 +288,7 @@ function delivery_run($argv, $argc){ if($normal_mode) { if($item_id == $item['id'] || $item['id'] == $item['parent']) - $atom .= atom_entry($item,'text',null,$owner,true); + $atom .= atom_entry($item,'text',null,$owner,true,(($top_level) ? $contact['id'] : 0)); } else $atom .= atom_entry($item,'text',null,$owner,true); diff --git a/include/items.php b/include/items.php index e5b640fd2..f45b40cc0 100644 --- a/include/items.php +++ b/include/items.php @@ -2832,7 +2832,7 @@ function atom_author($tag,$name,$uri,$h,$w,$photo) { return $o; } -function atom_entry($item,$type,$author,$owner,$comment = false) { +function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) { $a = get_app(); @@ -2844,7 +2844,7 @@ function atom_entry($item,$type,$author,$owner,$comment = false) { if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid']) - $body = fix_private_photos($item['body'],$owner['uid']); + $body = fix_private_photos($item['body'],$owner['uid'],$item,$cid); else $body = $item['body']; @@ -2927,14 +2927,17 @@ function atom_entry($item,$type,$author,$owner,$comment = false) { return $o; } -function fix_private_photos($s,$uid) { +function fix_private_photos($s,$uid, $item = null, $cid = 0) { $a = get_app(); - logger('fix_private_photos'); + + logger('fix_private_photos', LOGGER_DEBUG); + $site = substr($a->get_baseurl(),strpos($a->get_baseurl,'://')); if(preg_match("/\[img\](.*?)\[\/img\]/is",$s,$matches)) { $image = $matches[1]; - logger('fix_private_photos: found photo ' . $image); - if(stristr($image ,$a->get_baseurl() . '/photo/')) { + logger('fix_private_photos: found photo ' . $image, LOGGER_DEBUG); + if(stristr($image , $site . '/photo/')) { + $replace = false; $i = basename($image); $i = str_replace('.jpg','',$i); $x = strpos($i,'-'); @@ -2947,8 +2950,39 @@ function fix_private_photos($s,$uid) { intval($uid) ); if(count($r)) { - logger('replacing photo'); - $s = str_replace($image, 'data:image/jpg;base64,' . base64_encode($r[0]['data']), $s); + + // Check to see if we should replace this photo link with an embedded image + // 1. No need to do so if the photo is public + // 2. If there's a contact-id provided, see if they're in the access list + // for the photo. If so, embed it. + // 3. Otherwise, if we have an item, see if the item permissions match the photo + // permissions, regardless of order but first check to see if they're an exact + // match to save some processing overhead. + + // Currently we only embed one private photo per message so as not to hit import + // size limits at the receiving end. + + // To embed multiples, we would need to parse out the embedded photos on message + // receipt and limit size based only on the text component. Would also need to + // ignore all photos during bbcode translation and item localisation, as these + // will hit internal regex backtrace limits. + + if(has_permissions($r[0])) { + if($cid) { + $recips = enumerate_permissions($r[0]); + if(in_array($cid, $recips)) { + $replace = true; + } + } + elseif($item) { + if(compare_permissions($item,$r[0])) + $replace = true; + } + } + if($replace) { + logger('replacing photo'); + $s = str_replace($image, 'data:image/jpg;base64,' . base64_encode($r[0]['data']), $s); + } } } logger('fix_private_photos: replaced: ' . $s, LOGGER_DATA); @@ -2958,6 +2992,44 @@ function fix_private_photos($s,$uid) { } +function has_permissions($obj) { + if(($obj['allow_cid'] != '') || ($obj['allow_gid'] != '') || ($obj['deny_cid'] != '') || ($obj['deny_gid'] != '')) + return true; + return false; +} + +function compare_permissions($obj1,$obj2) { + // first part is easy. Check that these are exactly the same. + if(($obj1['allow_cid'] == $obj2['allow_cid']) + && ($obj1['allow_gid'] == $obj2['allow_gid']) + && ($obj1['deny_cid'] == $obj2['deny_cid']) + && ($obj1['deny_gid'] == $obj2['deny_gid'])) + return true; + + // This is harder. Parse all the permissions and compare the resulting set. + + $recipients1 = enumerate_permissions($obj1); + $recipients2 = enumerate_permissions($obj2); + sort($recipients1); + sort($recipients2); + if($recipients1 == $recipients2) + return true; + return false; +} + +// returns an array of contact-ids that are allowed to see this object + +function enumerate_permissions($obj) { + require_once('include/group.php'); + $allow_people = expand_acl($obj['allow_cid']); + $allow_groups = expand_groups(expand_acl($obj['allow_gid'])); + $deny_people = expand_acl($obj['deny_cid']); + $deny_groups = expand_groups(expand_acl($obj['deny_gid'])); + $recipients = array_unique(array_merge($allow_people,$allow_groups)); + $deny = array_unique(array_merge($deny_people,$deny_groups)); + $recipients = array_diff($recipients,$deny); + return $recipients; +} function item_getfeedtags($item) { $ret = array(); diff --git a/include/notifier.php b/include/notifier.php index cb4fb2a31..070e7a436 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -345,7 +345,7 @@ function notifier_run($argv, $argc){ if($mail) { $public_message = false; // mail is not public - $body = fix_private_photos($item['body'],$owner['uid']); + $body = fix_private_photos($item['body'],$owner['uid'],null,$message[0]['contact-id']); $atom .= replace_macros($mail_template, array( '$name' => xmlify($owner['name']), diff --git a/mod/settings.php b/mod/settings.php index 40fa55eea..e6eb4011f 100644 --- a/mod/settings.php +++ b/mod/settings.php @@ -15,6 +15,7 @@ function get_theme_config_file($theme){ } function settings_init(&$a) { + // These lines provide the javascript needed by the acl selector $a->page['htmlhead'] .= "