diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/colors.php | 5 | ||||
-rwxr-xr-x | include/controls.php | 2 | ||||
-rw-r--r-- | include/functions.php | 74 | ||||
-rwxr-xr-x | include/login_form.php | 9 | ||||
-rw-r--r-- | include/version.php | 47 |
5 files changed, 83 insertions, 54 deletions
diff --git a/include/colors.php b/include/colors.php index c441f7cb1..2ad958e94 100644 --- a/include/colors.php +++ b/include/colors.php @@ -202,10 +202,13 @@ function _color_unpack($hex, $normalize = false) { if (strpos($hex, '#') !== 0) $hex = _resolve_htmlcolor($hex); + else + $hex = substr($hex, 1); if (strlen($hex) == 4) { $hex = $hex[1] . $hex[1] . $hex[2] . $hex[2] . $hex[3] . $hex[3]; - } $c = hexdec($hex); + } + $c = hexdec($hex); for ($i = 16; $i >= 0; $i -= 8) { $out[] = (($c >> $i) & 0xFF) / ($normalize ? 255 : 1); } return $out; diff --git a/include/controls.php b/include/controls.php index 012bcf76c..8646ec15d 100755 --- a/include/controls.php +++ b/include/controls.php @@ -238,7 +238,7 @@ function stylesheet_tag($filename, $id = false) { $id_part = $id ? "id=\"$id\"" : ""; - return "<link rel=\"stylesheet\" $id_part type=\"text/css\" href=\"$filename?$timestamp\"/>\n"; + return "<link rel=\"stylesheet\" $id_part type=\"text/css\" data-orig-href=\"$filename\" href=\"$filename?$timestamp\"/>\n"; } function javascript_tag($filename) { diff --git a/include/functions.php b/include/functions.php index c326ac468..9cd352833 100644 --- a/include/functions.php +++ b/include/functions.php @@ -1,6 +1,6 @@ <?php define('EXPECTED_CONFIG_VERSION', 26); - define('SCHEMA_VERSION', 138); + define('SCHEMA_VERSION', 139); define('LABEL_BASE_INDEX', -1024); define('PLUGIN_FEED_BASE_INDEX', -128); @@ -63,6 +63,11 @@ define_default('MAX_CONDITIONAL_INTERVAL', 3600*12); // max interval between forced unconditional updates for servers // not complying with http if-modified-since (seconds) + define_default('MAX_FETCH_REQUESTS_PER_HOST', 25); + // a maximum amount of allowed HTTP requests per destination host + // during a single update (i.e. within PHP process lifetime) + // this is used to not cause excessive load on the origin server on + // e.g. feed subscription when all articles are being processes /* tunables end here */ @@ -159,6 +164,12 @@ Debug::log($msg); } + function reset_fetch_domain_quota() { + global $fetch_domain_hits; + + $fetch_domain_hits = []; + } + // TODO: max_size currently only works for CURL transfers // TODO: multiple-argument way is deprecated, first parameter is a hash now function fetch_file_contents($options /* previously: 0: $url , 1: $type = false, 2: $login = false, 3: $pass = false, @@ -171,6 +182,7 @@ global $fetch_last_modified; global $fetch_effective_url; global $fetch_curl_used; + global $fetch_domain_hits; $fetch_last_error = false; $fetch_last_error_code = -1; @@ -180,6 +192,9 @@ $fetch_last_modified = ""; $fetch_effective_url = ""; + if (!is_array($fetch_domain_hits)) + $fetch_domain_hits = []; + if (!is_array($options)) { // falling back on compatibility shim @@ -215,6 +230,7 @@ $followlocation = isset($options["followlocation"]) ? $options["followlocation"] : true; $max_size = isset($options["max_size"]) ? $options["max_size"] : MAX_DOWNLOAD_FILE_SIZE; // in bytes $http_accept = isset($options["http_accept"]) ? $options["http_accept"] : false; + $http_referrer = isset($options["http_referrer"]) ? $options["http_referrer"] : false; $url = ltrim($url, ' '); $url = str_replace(' ', '%20', $url); @@ -222,6 +238,14 @@ if (strpos($url, "//") === 0) $url = 'http:' . $url; + $url_host = parse_url($url, PHP_URL_HOST); + $fetch_domain_hits[$url_host] += 1; + + if ($fetch_domain_hits[$url_host] > MAX_FETCH_REQUESTS_PER_HOST) { + user_error("Exceeded fetch request quota for $url_host: " . $fetch_domain_hits[$url_host], E_USER_WARNING); + #return false; + } + if (!defined('NO_CURL') && function_exists('curl_init') && !ini_get("open_basedir")) { $fetch_curl_used = true; @@ -250,7 +274,9 @@ curl_setopt($ch, CURLOPT_USERAGENT, $useragent ? $useragent : SELF_USER_AGENT); curl_setopt($ch, CURLOPT_ENCODING, ""); - //curl_setopt($ch, CURLOPT_REFERER, $url); + + if ($http_referrer) + curl_setopt($ch, CURLOPT_REFERER, $http_referrer); if ($max_size) { curl_setopt($ch, CURLOPT_NOPROGRESS, false); @@ -378,6 +404,9 @@ if ($http_accept) array_push($context_options['http']['header'], "Accept: $http_accept"); + if ($http_referrer) + array_push($context_options['http']['header'], "Referer: $http_referrer"); + if (defined('_HTTP_PROXY')) { $context_options['http']['request_fulluri'] = true; $context_options['http']['proxy'] = _HTTP_PROXY; @@ -509,7 +538,7 @@ return ""; } - function authenticate_user($login, $password, $check_only = false) { + function authenticate_user($login, $password, $check_only = false, $service = false) { if (!SINGLE_USER_MODE) { $user_id = false; @@ -517,7 +546,7 @@ foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_AUTH_USER) as $plugin) { - $user_id = (int) $plugin->authenticate($login, $password); + $user_id = (int) $plugin->authenticate($login, $password, $service); if ($user_id) { $auth_module = strtolower(get_class($plugin)); @@ -531,7 +560,6 @@ session_regenerate_id(true); $_SESSION["uid"] = $user_id; - $_SESSION["version"] = VERSION_STATIC; $_SESSION["auth_module"] = $auth_module; $pdo = DB::pdo(); @@ -593,7 +621,7 @@ } function clean_filename($filename) { - return basename(preg_replace("/\.\.|[\/\\\]/", "", $filename)); + return basename(preg_replace("/\.\.|[\/\\\]/", "", clean($filename))); } function make_password($length = 12) { @@ -1013,10 +1041,12 @@ __("Navigation") => array( "next_feed" => __("Open next feed"), "prev_feed" => __("Open previous feed"), - "next_article" => __("Open next article"), - "prev_article" => __("Open previous article"), - "next_article_noscroll" => __("Open next article (don't scroll long articles)"), - "prev_article_noscroll" => __("Open previous article (don't scroll long articles)"), + "next_article_or_scroll" => __("Open next article (in combined mode, scroll down)"), + "prev_article_or_scroll" => __("Open previous article (in combined mode, scroll up)"), + "next_article_page" => __("Scroll article by one page down"), + "prev_article_page" => __("Scroll article by one page up"), + "next_article_noscroll" => __("Open next article"), + "prev_article_noscroll" => __("Open previous article"), "next_article_noexpand" => __("Move to next article (don't expand or mark read)"), "prev_article_noexpand" => __("Move to previous article (don't expand or mark read)"), "search_dialog" => __("Show search dialog")), @@ -1030,6 +1060,8 @@ "catchup_above" => __("Mark above as read"), "article_scroll_down" => __("Scroll down"), "article_scroll_up" => __("Scroll up"), + "article_page_down" => __("Scroll down page"), + "article_page_up" => __("Scroll up page"), "select_article_cursor" => __("Select article under cursor"), "email_article" => __("Email article"), "close_article" => __("Close/collapse article"), @@ -1069,7 +1101,6 @@ "create_label" => __("Create label"), "create_filter" => __("Create filter"), "collapse_sidebar" => __("Un/collapse sidebar"), - "toggle_night_mode" => __("Toggle night mode"), "help_dialog" => __("Show help dialog")) ); @@ -1084,10 +1115,14 @@ $hotkeys = array( "k" => "next_feed", "j" => "prev_feed", - "n" => "next_article", - "p" => "prev_article", - "(38)|Up" => "prev_article", - "(40)|Down" => "next_article", + "n" => "next_article_noscroll", + "p" => "prev_article_noscroll", + //"(33)|PageUp" => "prev_article_page", + //"(34)|PageDown" => "next_article_page", + "*(33)|Shift+PgUp" => "article_page_up", + "*(34)|Shift+PgDn" => "article_page_down", + "(38)|Up" => "prev_article_or_scroll", + "(40)|Down" => "next_article_or_scroll", "*(38)|Shift+Up" => "article_scroll_up", "*(40)|Shift+Down" => "article_scroll_down", "^(38)|Ctrl+Up" => "prev_article_noscroll", @@ -1136,7 +1171,6 @@ "c l" => "create_label", "c f" => "create_filter", "c s" => "collapse_sidebar", - "a N" => "toggle_night_mode", "?" => "help_dialog", ); @@ -1221,13 +1255,11 @@ } function iframe_whitelisted($entry) { - $whitelist = array("youtube.com", "youtu.be", "vimeo.com", "player.vimeo.com"); - @$src = parse_url($entry->getAttribute("src"), PHP_URL_HOST); if ($src) { - foreach ($whitelist as $w) { - if ($src == $w || $src == "www.$w") + foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_IFRAME_WHITELISTED) as $plugin) { + if ($plugin->hook_iframe_whitelisted($src)) return true; } } @@ -1554,7 +1586,7 @@ $value = get_pref('USER_STYLESHEET'); if ($value) { - print "<style type=\"text/css\">"; + print "<style type='text/css' id='user_css_style'>"; print str_replace("<br/>", "\n", $value); print "</style>"; } diff --git a/include/login_form.php b/include/login_form.php index 6c6aaf8cf..941321fc0 100755 --- a/include/login_form.php +++ b/include/login_form.php @@ -91,11 +91,12 @@ function bwLimitChange(elem) { dojoType="dijit.form.TextBox" class="input input-text" value="<?php echo $_SESSION["fake_password"] ?>"/> - - <?php if (strpos(PLUGINS, "auth_internal") !== FALSE) { ?> - <a href="public.php?op=forgotpass"><?php echo __("I forgot my password") ?></a> - <?php } ?> </fieldset> + <?php if (strpos(PLUGINS, "auth_internal") !== FALSE) { ?> + <fieldset class="align-right"> + <a href="public.php?op=forgotpass"><?php echo __("I forgot my password") ?></a> + </fieldset> + <?php } ?> <fieldset> <label><?php echo __("Profile:") ?></label> diff --git a/include/version.php b/include/version.php index db5c2ec80..d1c5e03b5 100644 --- a/include/version.php +++ b/include/version.php @@ -1,43 +1,36 @@ <?php - define('VERSION_STATIC', '19.8'); - function get_version() { - date_default_timezone_set('UTC'); - $root_dir = dirname(dirname(__FILE__)); - - if (is_dir("$root_dir/.git") && file_exists("$root_dir/.git/HEAD")) { - $head = trim(file_get_contents("$root_dir/.git/HEAD")); - - if ($head) { - $matches = array(); + /* for package maintainers who don't use git: if version_static.txt exists in tt-rss root + directory, its contents are displayed instead of git commit-based version, this could be generated + based on source git tree commit used when creating the package */ - if (preg_match("/^ref: (.*)/", $head, $matches)) { - $ref = $matches[1]; + function get_version(&$git_commit = false, &$git_timestamp = false) { + $version = "UNKNOWN (Unsupported)"; - if (!file_exists("$root_dir/.git/$ref")) - return VERSION_STATIC; - $suffix = substr(trim(file_get_contents("$root_dir/.git/$ref")), 0, 7); - $timestamp = filemtime("$root_dir/.git/$ref"); + date_default_timezone_set('UTC'); + $root_dir = dirname(dirname(__FILE__)); - define("GIT_VERSION_HEAD", $suffix); - define("GIT_VERSION_TIMESTAMP", $timestamp); + if (file_exists("$root_dir/version_static.txt")) { + $version = trim(file_get_contents("$root_dir/version_static.txt")) . " (Unsupported)"; + } else if (is_dir("$root_dir/.git")) { + $rc = 0; + $output = []; - return VERSION_STATIC . " ($suffix)"; + exec("git log --pretty='%ct %h' -n1 HEAD " . escapeshellarg($root_dir), $output, $rc); - } else { - $suffix = substr(trim($head), 0, 7); - $timestamp = filemtime("$root_dir/.git/HEAD"); + if ($rc == 0) { + if (is_array($output) && count($output) > 0) { + list ($timestamp, $commit) = explode(" ", $output[0], 2); - define("GIT_VERSION_HEAD", $suffix); - define("GIT_VERSION_TIMESTAMP", $timestamp); + $git_commit = $commit; + $git_timestamp = $timestamp; - return VERSION_STATIC . " ($suffix)"; + $version = strftime("%y.%m", $timestamp) . "-$commit"; } } } - return VERSION_STATIC; - + return $version; } define('VERSION', get_version()); |