diff options
Diffstat (limited to 'include/items.php')
-rw-r--r-- | include/items.php | 126 |
1 files changed, 85 insertions, 41 deletions
diff --git a/include/items.php b/include/items.php index f204745bb..45d8b62c0 100644 --- a/include/items.php +++ b/include/items.php @@ -2,6 +2,7 @@ require_once('bbcode.php'); require_once('oembed.php'); +require_once('include/salmon.php'); function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0) { @@ -376,6 +377,21 @@ function get_atom_elements($feed,$item) { } + /** + * If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it. + */ + + $have_real_body = false; + + $rawenv = $item->get_item_tags(NAMESPACE_DFRN, 'env'); + if($rawenv) { + $have_real_body = true; + $res['body'] = $rawenv[0]['data']; + $res['body'] = str_replace(array(' ',"\t","\r","\n"), array('','','',''),$res['body']); + // make sure nobody is trying to sneak some html tags by us + $res['body'] = notags(base64url_decode($res['body'])); + } + $maxlen = get_max_import_size(); if($maxlen && (strlen($res['body']) > $maxlen)) $res['body'] = substr($res['body'],0, $maxlen); @@ -391,7 +407,7 @@ function get_atom_elements($feed,$item) { // html. - if((strpos($res['body'],'<')) || (strpos($res['body'],'>'))) { + if((strpos($res['body'],'<') !== false) || (strpos($res['body'],'>') !== false)) { $res['body'] = preg_replace('#<object[^>]+>.+?' . 'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s', '[youtube]$1[/youtube]', $res['body']); @@ -410,10 +426,7 @@ function get_atom_elements($feed,$item) { $res['body'] = html2bbcode($res['body']); } - else - $res['body'] = escape_tags($res['body']); - $allow = $item->get_item_tags(NAMESPACE_DFRN,'comment-allow'); if($allow && $allow[0]['data'] == 1) $res['last-child'] = 1; @@ -439,14 +452,16 @@ function get_atom_elements($feed,$item) { $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10,'updated'); if($rawedited) - $res['edited'] = unxmlify($rawcreated[0]['data']); + $res['edited'] = unxmlify($rawedited[0]['data']); + if((x($res,'edited')) && (! (x($res,'created')))) + $res['created'] = $res['edited']; if(! $res['created']) - $res['created'] = $item->get_date(); + $res['created'] = $item->get_date('c'); if(! $res['edited']) - $res['edited'] = $item->get_date(); + $res['edited'] = $item->get_date('c'); $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner'); @@ -510,7 +525,7 @@ function get_atom_elements($feed,$item) { $body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data']; // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events $res['object'] .= '<orig>' . xmlify($body) . '</orig>' . "\n"; - if((strpos($body,'<')) || (strpos($body,'>'))) { + if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) { $body = preg_replace('#<object[^>]+>.+?' . 'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s', '[youtube]$1[/youtube]', $body); @@ -522,8 +537,6 @@ function get_atom_elements($feed,$item) { $body = $purifier->purify($body); $body = html2bbcode($body); } - else - $body = escape_tags($body); $res['object'] .= '<content>' . $body . '</content>' . "\n"; } @@ -551,7 +564,7 @@ function get_atom_elements($feed,$item) { $body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data']; // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events $res['object'] .= '<orig>' . xmlify($body) . '</orig>' . "\n"; - if((strpos($body,'<')) || (strpos($body,'>'))) { + if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) { $body = preg_replace('#<object[^>]+>.+?' . 'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s', '[youtube]$1[/youtube]', $body); @@ -563,8 +576,6 @@ function get_atom_elements($feed,$item) { $body = $purifier->purify($body); $body = html2bbcode($body); } - else - $body = escape_tags($body); $res['target'] .= '<content>' . $body . '</content>' . "\n"; } @@ -600,7 +611,7 @@ function encode_rel_links($links) { return xmlify($o); } -function item_store($arr) { +function item_store($arr,$force_parent = false) { if($arr['gravity']) $arr['gravity'] = intval($arr['gravity']); @@ -613,6 +624,13 @@ function item_store($arr) { if(! x($arr,'type')) $arr['type'] = 'remote'; + + // Shouldn't happen but we want to make absolutely sure it doesn't leak from a plugin. + + if((strpos($arr['body'],'<') !== false) || (strpos($arr['body'],'>') !== false)) + $arr['body'] = strip_tags($arr['body']); + + $arr['wall'] = ((x($arr,'wall')) ? intval($arr['wall']) : 0); $arr['uri'] = ((x($arr,'uri')) ? notags(trim($arr['uri'])) : random_string()); $arr['author-name'] = ((x($arr,'author-name')) ? notags(trim($arr['author-name'])) : ''); @@ -641,20 +659,7 @@ function item_store($arr) { $arr['deny_cid'] = ((x($arr,'deny_cid')) ? trim($arr['deny_cid']) : ''); $arr['deny_gid'] = ((x($arr,'deny_gid')) ? trim($arr['deny_gid']) : ''); $arr['private'] = ((x($arr,'private')) ? intval($arr['private']) : 0 ); - $arr['body'] = ((x($arr,'body')) ? escape_tags(trim($arr['body'])) : ''); - - // The content body has been through a lot of filtering and transport escaping by now. - // We don't want to skip any filters, however a side effect of all this filtering - // is that ampersands and <> may have been double encoded, depending on which filter chain - // they came through. - - $arr['body'] = str_replace( - array('&amp;', '&gt;', '&lt;', '&quot;'), - array('&' , '>' , '<', '"'), - $arr['body'] - ); - - + $arr['body'] = ((x($arr,'body')) ? trim($arr['body']) : ''); if($arr['parent-uri'] === $arr['uri']) { $parent_id = 0; @@ -690,8 +695,20 @@ function item_store($arr) { $deny_gid = $r[0]['deny_gid']; } else { - logger('item_store: item parent was not found - ignoring item'); - return 0; + + // Allow one to see reply tweets from status.net even when + // we don't have or can't see the original post. + + if($force_parent) { + logger('item_store: $force_parent=true, reply converted to top-level post.'); + $parent_id = 0; + $arr['thr-parent'] = $arr['parent-uri']; + $arr['parent-uri'] = $arr['uri']; + } + else { + logger('item_store: item parent was not found - ignoring item'); + return 0; + } } } @@ -763,7 +780,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { $a = get_app(); - if((! strlen($contact['dfrn-id'])) && (! $contact['duplex']) && (! ($owner['page-flags'] == PAGE_COMMUNITY))) + if((! strlen($contact['issued-id'])) && (! $contact['duplex']) && (! ($owner['page-flags'] == PAGE_COMMUNITY))) return 3; $idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']); @@ -795,6 +812,12 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { if(! $xml) return 3; + if(strpos($xml,'<?xml') === false) { + logger('dfrn_deliver: no valid XML returned'); + logger('dfrn_deliver: returned XML: ' . $xml, LOGGER_DATA); + return 3; + } + $res = simplexml_load_string($xml); if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id))) @@ -803,19 +826,20 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { $postvars = array(); $sent_dfrn_id = hex2bin((string) $res->dfrn_id); $challenge = hex2bin((string) $res->challenge); + $dfrn_version = (float) (($res->dfrn_version) ? $res->dfrn_version : 2.0); $rino_allowed = ((intval($res->rino) === 1) ? 1 : 0); $final_dfrn_id = ''; - if(($contact['duplex'] && strlen($contact['prvkey'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) { - openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']); - openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']); - } - else { + if(($contact['duplex'] && strlen($contact['pubkey'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) { openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']); openssl_public_decrypt($challenge,$postvars['challenge'],$contact['pubkey']); } + else { + openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']); + openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']); + } $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.')); @@ -849,11 +873,22 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { $postvars['data'] = $data; logger('rino: sent key = ' . $key); - if(($contact['duplex'] && strlen($contact['prvkey'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) { - openssl_private_encrypt($key,$postvars['key'],$contact['prvkey']); + + if($dfrn_version >= 2.1) { + if(($contact['duplex'] && strlen($contact['pubkey'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) { + openssl_public_encrypt($key,$postvars['key'],$contact['pubkey']); + } + else { + openssl_private_encrypt($key,$postvars['key'],$contact['prvkey']); + } } else { - openssl_public_encrypt($key,$postvars['key'],$contact['pubkey']); + if(($contact['duplex'] && strlen($contact['prvkey'])) || ($owner['page-flags'] == PAGE_COMMUNITY)) { + openssl_private_encrypt($key,$postvars['key'],$contact['prvkey']); + } + else { + openssl_public_encrypt($key,$postvars['key'],$contact['pubkey']); + } } logger('md5 rawkey ' . md5($postvars['key'])); @@ -871,6 +906,13 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) { if((! $curl_stat) || (! strlen($xml))) return(-1); // timed out + + if(strpos($xml,'<?xml') === false) { + logger('dfrn_deliver: phase 2: no valid XML returned'); + logger('dfrn_deliver: phase 2: returned XML: ' . $xml, LOGGER_DATA); + return 3; + } + $res = simplexml_load_string($xml); return $res->status; @@ -1164,8 +1206,9 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) { continue; } $datarray = get_atom_elements($feed,$item); - + $force_parent = false; if($contact['network'] === 'stat') { + $force_parent = true; if(strlen($datarray['title'])) unset($datarray['title']); $r = q("UPDATE `item` SET `last-child` = 0, `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d", @@ -1188,7 +1231,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0) { $datarray['gravity'] = GRAVITY_LIKE; } - $r = item_store($datarray); + $r = item_store($datarray,$force_parent); continue; } @@ -1421,6 +1464,7 @@ function atom_entry($item,$type,$author,$owner,$comment = false) { $o .= '<title>' . xmlify($item['title']) . '</title>' . "\r\n"; $o .= '<published>' . xmlify(datetime_convert('UTC','UTC',$item['created'] . '+00:00',ATOM_TIME)) . '</published>' . "\r\n"; $o .= '<updated>' . xmlify(datetime_convert('UTC','UTC',$item['edited'] . '+00:00',ATOM_TIME)) . '</updated>' . "\r\n"; + $o .= '<dfrn:env>' . base64url_encode($item['body'], true) . '</dfrn:env>' . "\r\n"; $o .= '<content type="' . $type . '" >' . xmlify(($type === 'html') ? bbcode($item['body']) : $item['body']) . '</content>' . "\r\n"; $o .= '<link rel="alternate" href="' . xmlify($a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id']) . '" />' . "\r\n"; if($comment) |