X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=include%2Ffunctions.php;h=9125df3bd8a367cd65cca22d4be2596d67cc77b1;hb=07fd4f8d9d4f301f5ad88ff9e80f042fc3eb0c36;hp=a4e0e4d0221b70e579086dae9e0187c5406add86;hpb=c5c3a0a2a8febaa2b1ebcae6c17ff4398a9da6c7;p=tt-rss.git diff --git a/include/functions.php b/include/functions.php index a4e0e4d0..9125df3b 100755 --- a/include/functions.php +++ b/include/functions.php @@ -13,7 +13,6 @@ $fetch_last_error_content = false; // curl only for the time being $fetch_effective_url = false; $fetch_curl_used = false; - $suppress_debugging = false; libxml_disable_entity_loader(true); @@ -156,67 +155,11 @@ $schema_version = false; - function _debug_suppress($suppress) { - global $suppress_debugging; - - $suppress_debugging = $suppress; + // TODO: compat wrapper, remove at some point + function _debug($msg) { + Debug::log($msg); } - /** - * Print a timestamped debug message. - * - * @param string $msg The debug message. - * @return void - */ - function _debug($msg, $show = true) { - global $suppress_debugging; - - //echo "[$suppress_debugging] $msg $show\n"; - - if ($suppress_debugging) return false; - - $ts = strftime("%H:%M:%S", time()); - if (function_exists('posix_getpid')) { - $ts = "$ts/" . posix_getpid(); - } - - if ($show && !(defined('QUIET') && QUIET)) { - print "[$ts] $msg\n"; - } - - if (defined('LOGFILE')) { - $fp = fopen(LOGFILE, 'a+'); - - if ($fp) { - $locked = false; - - if (function_exists("flock")) { - $tries = 0; - - // try to lock logfile for writing - while ($tries < 5 && !$locked = flock($fp, LOCK_EX | LOCK_NB)) { - sleep(1); - ++$tries; - } - - if (!$locked) { - fclose($fp); - return; - } - } - - fputs($fp, "[$ts] $msg\n"); - - if (function_exists("flock")) { - flock($fp, LOCK_UN); - } - - fclose($fp); - } - } - - } // function _debug - /** * Purge a feed old posts. * @@ -227,7 +170,7 @@ * @access public * @return void */ - function purge_feed($feed_id, $purge_interval, $debug = false) { + function purge_feed($feed_id, $purge_interval) { if (!$purge_interval) $purge_interval = feed_purge_interval($feed_id); @@ -292,9 +235,7 @@ CCache::update($feed_id, $owner_uid); - if ($debug) { - _debug("Purged feed $feed_id ($purge_interval): deleted $rows articles"); - } + Debug::log("Purged feed $feed_id ($purge_interval): deleted $rows articles"); return $rows; } // function purge_feed @@ -421,7 +362,7 @@ // holy shit closures in php // download & upload are *expected* sizes respectively, could be zero curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function($curl_handle, $download_size, $downloaded, $upload_size, $uploaded) use( &$max_size) { - //_debug("[curl progressfunction] $downloaded $max_size"); + Debug::log("[curl progressfunction] $downloaded $max_size", Debug::$LOG_EXTENDED); return ($downloaded > $max_size) ? 1 : 0; // if max size is set, abort when exceeding it }); @@ -700,22 +641,26 @@ if (!SINGLE_USER_MODE) { $user_id = false; + $auth_module = false; foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_AUTH_USER) as $plugin) { $user_id = (int) $plugin->authenticate($login, $password); if ($user_id) { - $_SESSION["auth_module"] = strtolower(get_class($plugin)); + $auth_module = strtolower(get_class($plugin)); break; } } if ($user_id && !$check_only) { - @session_start(); + + session_start(); + session_regenerate_id(true); $_SESSION["uid"] = $user_id; $_SESSION["version"] = VERSION_STATIC; + $_SESSION["auth_module"] = $auth_module; $pdo = DB::pdo(); $sth = $pdo->prepare("SELECT login,access_level,pwd_hash FROM ttrss_users @@ -811,10 +756,11 @@ } function logout_user() { - session_destroy(); + @session_destroy(); if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time()-42000, '/'); } + session_commit(); } function validate_csrf($csrf_token) { @@ -856,8 +802,7 @@ } if (!$_SESSION["uid"]) { - @session_destroy(); - setcookie(session_name(), '', time()-42000, '/'); + logout_user(); render_login_form(); exit; @@ -1219,8 +1164,7 @@ "feed_debug_viewfeed" => __("Debug viewfeed()"), "catchup_all" => __("Mark all feeds as read"), "cat_toggle_collapse" => __("Un/collapse current category"), - "toggle_combined_mode" => __("Toggle combined mode"), - "toggle_cdm_expanded" => __("Toggle auto expand in combined mode")), + "toggle_combined_mode" => __("Toggle combined mode")), __("Go to") => array( "goto_all" => __("All articles"), "goto_fresh" => __("Fresh"), @@ -1288,7 +1232,6 @@ "f *d" => "feed_debug_update", "f *g" => "feed_debug_viewfeed", "f *c" => "toggle_combined_mode", - "f c" => "toggle_cdm_expanded", "*q" => "catchup_all", "x" => "cat_toggle_collapse", // "goto" => array( @@ -1365,7 +1308,6 @@ $data["num_feeds"] = (int) $num_feeds; $data['last_article_id'] = Article::getLastArticleId(); - $data['cdm_expanded'] = get_pref('CDM_EXPANDED'); $data['dep_ts'] = calculate_dep_timestamp(); $data['reload_on_ts_change'] = !defined('_NO_RELOAD_ON_TS_CHANGE'); @@ -1564,38 +1506,31 @@ return false; } - function sanitize($str, $force_remove_images = false, $owner = false, $site_url = false, $highlight_words = false, $article_id = false) { - if (!$owner) $owner = $_SESSION["uid"]; - - $res = trim($str); if (!$res) return ''; + // check for locally cached (media) URLs and rewrite to local versions + // this is called separately after sanitize() and plugin render article hooks to allow + // plugins work on original source URLs used before caching + function rewrite_cached_urls($str) { $charset_hack = ' '; - $res = trim($res); if (!$res) return ''; - - libxml_use_internal_errors(true); + $res = trim($str); if (!$res) return ''; $doc = new DOMDocument(); $doc->loadHTML($charset_hack . $res); $xpath = new DOMXPath($doc); - $rewrite_base_url = $site_url ? $site_url : get_self_url_prefix(); + $entries = $xpath->query('(//img[@src]|//video[@poster]|//video/source[@src]|//audio/source[@src])'); - $entries = $xpath->query('(//a[@href]|//img[@src]|//video/source[@src]|//audio/source[@src])'); + $need_saving = false; foreach ($entries as $entry) { - if ($entry->hasAttribute('href')) { - $entry->setAttribute('href', - rewrite_relative_url($rewrite_base_url, $entry->getAttribute('href'))); - - $entry->setAttribute('rel', 'noopener noreferrer'); - } + if ($entry->hasAttribute('src') || $entry->hasAttribute('poster')) { - if ($entry->hasAttribute('src')) { - $src = rewrite_relative_url($rewrite_base_url, $entry->getAttribute('src')); + // should be already absolutized because this is called after sanitize() + $src = $entry->hasAttribute('poster') ? $entry->getAttribute('poster') : $entry->getAttribute('src'); $cached_filename = CACHE_DIR . '/images/' . sha1($src); if (file_exists($cached_filename)) { @@ -1613,14 +1548,58 @@ $src = get_self_url_prefix() . '/public.php?op=cached_url&hash=' . sha1($src) . $suffix; - if ($entry->hasAttribute('srcset')) { - $entry->removeAttribute('srcset'); - } + if ($entry->hasAttribute('poster')) + $entry->setAttribute('poster', $src); + else + $entry->setAttribute('src', $src); - if ($entry->hasAttribute('sizes')) { - $entry->removeAttribute('sizes'); - } + $need_saving = true; } + } + } + + if ($need_saving) { + $doc->removeChild($doc->firstChild); //remove doctype + $res = $doc->saveHTML(); + } + + return $res; + } + + function sanitize($str, $force_remove_images = false, $owner = false, $site_url = false, $highlight_words = false, $article_id = false) { + if (!$owner) $owner = $_SESSION["uid"]; + + $res = trim($str); if (!$res) return ''; + + $charset_hack = ' + + '; + + $res = trim($res); if (!$res) return ''; + + libxml_use_internal_errors(true); + + $doc = new DOMDocument(); + $doc->loadHTML($charset_hack . $res); + $xpath = new DOMXPath($doc); + + $rewrite_base_url = $site_url ? $site_url : get_self_url_prefix(); + + $entries = $xpath->query('(//a[@href]|//img[@src]|//video/source[@src]|//audio/source[@src])'); + + foreach ($entries as $entry) { + + if ($entry->hasAttribute('href')) { + $entry->setAttribute('href', + rewrite_relative_url($rewrite_base_url, $entry->getAttribute('href'))); + + $entry->setAttribute('rel', 'noopener noreferrer'); + } + + if ($entry->hasAttribute('src')) { + $src = rewrite_relative_url($rewrite_base_url, $entry->getAttribute('src')); + + // cache stuff has gone to rewrite_cached_urls() $entry->setAttribute('src', $src); } @@ -1645,22 +1624,32 @@ } } } + } - if (($owner && get_pref("STRIP_IMAGES", $owner)) || - $force_remove_images || $_SESSION["bw_limit"]) { + if ($entry->hasAttribute('src') && + ($owner && get_pref("STRIP_IMAGES", $owner)) || $force_remove_images || $_SESSION["bw_limit"]) { - $p = $doc->createElement('p'); + $p = $doc->createElement('p'); - $a = $doc->createElement('a'); - $a->setAttribute('href', $entry->getAttribute('src')); + $a = $doc->createElement('a'); + $a->setAttribute('href', $entry->getAttribute('src')); - $a->appendChild(new DOMText($entry->getAttribute('src'))); - $a->setAttribute('target', '_blank'); - $a->setAttribute('rel', 'noopener noreferrer'); + $a->appendChild(new DOMText($entry->getAttribute('src'))); + $a->setAttribute('target', '_blank'); + $a->setAttribute('rel', 'noopener noreferrer'); - $p->appendChild($a); + $p->appendChild($a); + + if ($entry->nodeName == 'source') { + + if ($entry->parentNode && $entry->parentNode->parentNode) + $entry->parentNode->parentNode->replaceChild($p, $entry->parentNode); + + } else if ($entry->nodeName == 'img') { + + if ($entry->parentNode) + $entry->parentNode->replaceChild($p, $entry); - $entry->parentNode->replaceChild($p, $entry); } } @@ -1772,6 +1761,10 @@ array_push($attrs_to_remove, $attr); } + if (strpos($attr->nodeName, "data-") === 0) { + array_push($attrs_to_remove, $attr); + } + if ($attr->nodeName == 'href' && stripos($attr->value, 'javascript:') === 0) { array_push($attrs_to_remove, $attr); } @@ -2101,7 +2094,7 @@ $sth = $pdo->prepare("SELECT access_key FROM ttrss_access_keys WHERE feed_id = ? AND is_cat = ? AND owner_uid = ?"); - $sth->execute([$feed_id, (int)$is_cat, $owner_uid]); + $sth->execute([$feed_id, $is_cat, $owner_uid]); if ($row = $sth->fetch()) { return $row["access_key"]; @@ -2112,7 +2105,7 @@ (access_key, feed_id, is_cat, owner_uid) VALUES (?, ?, ?, ?)"); - $sth->execute([$key, $feed_id, (int)$is_cat, $owner_uid]); + $sth->execute([$key, $feed_id, $is_cat, $owner_uid]); return $key; } @@ -2564,6 +2557,9 @@ should be loaded systemwide in config.php */ function send_local_file($filename) { if (file_exists($filename)) { + + if (is_writable($filename)) touch($filename); + $tmppluginhost = new PluginHost(); $tmppluginhost->load(PLUGINS, PluginHost::KIND_SYSTEM); @@ -2586,13 +2582,7 @@ $stamp = gmdate("D, d M Y H:i:s", filemtime($filename)) . " GMT"; header("Last-Modified: $stamp", true); - if (defined('_NGINX_XACCEL_PREFIX') && _NGINX_XACCEL_PREFIX) { - header("X-Accel-Redirect: " . _NGINX_XACCEL_PREFIX . "/" . $filename); - - return false; - } else { - return readfile($filename); - } + return readfile($filename); } else { return false; }