summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/db-prefs.php6
-rw-r--r--include/db.php6
-rw-r--r--include/digest.php28
-rw-r--r--include/feedbrowser.php2
-rw-r--r--include/functions.php535
-rw-r--r--include/labels.php9
-rw-r--r--include/localized_schema.php4
-rw-r--r--include/login_form.php16
-rw-r--r--include/rssfuncs.php79
-rw-r--r--include/sanity_check.php12
-rw-r--r--include/sanity_config.php2
-rw-r--r--include/sessions.php6
-rw-r--r--include/version.php2
13 files changed, 485 insertions, 222 deletions
diff --git a/include/db-prefs.php b/include/db-prefs.php
index 641e9d1dd..f6a78939b 100644
--- a/include/db-prefs.php
+++ b/include/db-prefs.php
@@ -44,7 +44,7 @@
function get_pref($link, $pref_name, $user_id = false, $die_on_error = false) {
- $pref_name = db_escape_string($pref_name);
+ $pref_name = db_escape_string($link, $pref_name);
$prefs_cache = true;
$profile = false;
@@ -115,8 +115,8 @@
}
function set_pref($link, $pref_name, $value, $user_id = false, $strip_tags = true) {
- $pref_name = db_escape_string($pref_name);
- $value = db_escape_string($value, $strip_tags);
+ $pref_name = db_escape_string($link, $pref_name);
+ $value = db_escape_string($link, $value, $strip_tags);
if (!$user_id) {
$user_id = $_SESSION["uid"];
diff --git a/include/db.php b/include/db.php
index f1a7af363..0479df6a9 100644
--- a/include/db.php
+++ b/include/db.php
@@ -41,13 +41,13 @@ function db_connect($host, $user, $pass, $db) {
}
}
-function db_escape_string($s, $strip_tags = true) {
+function db_escape_string($link, $s, $strip_tags = true) {
if ($strip_tags) $s = strip_tags($s);
if (DB_TYPE == "pgsql") {
- return pg_escape_string($s);
+ return pg_escape_string($link, $s);
} else {
- return mysql_real_escape_string($s);
+ return mysql_real_escape_string($s, $link);
}
}
diff --git a/include/digest.php b/include/digest.php
index 93ce373a2..ab29d9432 100644
--- a/include/digest.php
+++ b/include/digest.php
@@ -8,7 +8,7 @@
*/
function send_headlines_digests($link, $debug = false) {
- require_once 'lib/phpmailer/class.phpmailer.php';
+ require_once 'classes/ttrssmailer.php';
$user_limit = 15; // amount of users to process (e.g. emails to send out)
$limit = 1000; // maximum amount of headlines to include
@@ -50,31 +50,9 @@
if ($headlines_count > 0) {
- $mail = new PHPMailer();
+ $mail = new ttrssMailer();
- $mail->PluginDir = "lib/phpmailer/";
- $mail->SetLanguage("en", "lib/phpmailer/language/");
-
- $mail->CharSet = "UTF-8";
-
- $mail->From = SMTP_FROM_ADDRESS;
- $mail->FromName = SMTP_FROM_NAME;
- $mail->AddAddress($line["email"], $line["login"]);
-
- if (SMTP_HOST) {
- $mail->Host = SMTP_HOST;
- $mail->Mailer = "smtp";
- $mail->SMTPAuth = SMTP_LOGIN != '';
- $mail->Username = SMTP_LOGIN;
- $mail->Password = SMTP_PASSWORD;
- }
-
- $mail->IsHTML(true);
- $mail->Subject = DIGEST_SUBJECT;
- $mail->Body = $digest;
- $mail->AltBody = $digest_text;
-
- $rc = $mail->Send();
+ $rc = $mail->quickMail($line["email"], $line["login"] , DIGEST_SUBJECT, $digest, $digest_text);
if (!$rc && $debug) print "ERROR: " . $mail->ErrorInfo;
diff --git a/include/feedbrowser.php b/include/feedbrowser.php
index 5b33fb73c..e5ee4a70d 100644
--- a/include/feedbrowser.php
+++ b/include/feedbrowser.php
@@ -80,7 +80,7 @@
$class = ($feedctr % 2) ? "even" : "odd";
if ($line['articles_archived'] > 0) {
- $archived = sprintf(__("%d archived articles"), $line['articles_archived']);
+ $archived = sprintf(ngettext("%d archived article", "%d archived articles", $line['articles_archived']), $line['articles_archived']);
$archived = "&nbsp;<span class='subscribers'>($archived)</span>";
} else {
$archived = '';
diff --git a/include/functions.php b/include/functions.php
index f17828d1d..a9c7d95f5 100644
--- a/include/functions.php
+++ b/include/functions.php
@@ -1,6 +1,6 @@
<?php
define('EXPECTED_CONFIG_VERSION', 26);
- define('SCHEMA_VERSION', 104);
+ define('SCHEMA_VERSION', 108);
$fetch_last_error = false;
$pluginhost = false;
@@ -44,6 +44,7 @@
$tr = array(
"auto" => "Detect automatically",
"ca_CA" => "Català",
+ "cs_CZ" => "Česky",
"en_US" => "English",
"es_ES" => "Español",
"de_DE" => "Deutsch",
@@ -51,7 +52,9 @@
"hu_HU" => "Magyar (Hungarian)",
"it_IT" => "Italiano",
"ja_JP" => "日本語 (Japanese)",
+ "lv_LV" => "Latviešu",
"nb_NO" => "Norwegian bokmål",
+ "nl_NL" => "Dutch",
"pl_PL" => "Polski",
"ru_RU" => "Русский",
"pt_BR" => "Portuguese/Brazil",
@@ -73,10 +76,7 @@
$lang = _TRANSLATION_OVERRIDE_DEFAULT;
}
- /* In login action of mobile version */
- if ($_POST["language"] && defined('MOBILE_VERSION')) {
- $lang = $_POST["language"];
- } else if ($_SESSION["language"] && $_SESSION["language"] != "auto") {
+ if ($_SESSION["language"] && $_SESSION["language"] != "auto") {
$lang = $_SESSION["language"];
}
@@ -87,11 +87,7 @@
_setlocale(LC_ALL, $lang);
}
- if (defined('MOBILE_VERSION')) {
- _bindtextdomain("messages", "../locale");
- } else {
- _bindtextdomain("messages", "locale");
- }
+ _bindtextdomain("messages", "locale");
_textdomain("messages");
_bind_textdomain_codeset("messages", "UTF-8");
@@ -109,7 +105,6 @@
ini_set('user_agent', SELF_USER_AGENT);
require_once 'lib/pubsubhubbub/publisher.php';
- require_once 'lib/htmLawed.php';
$tz_offset = -1;
$utc_tz = new DateTimeZone('UTC');
@@ -122,14 +117,24 @@
* @return void
*/
function _debug($msg) {
- if (defined('QUIET') && QUIET) {
- return;
- }
$ts = strftime("%H:%M:%S", time());
if (function_exists('posix_getpid')) {
$ts = "$ts/" . posix_getpid();
}
- print "[$ts] $msg\n";
+
+ if (!(defined('QUIET') && QUIET)) {
+ print "[$ts] $msg\n";
+ }
+
+ if (defined('LOGFILE')) {
+ $fp = fopen(LOGFILE, 'a+');
+
+ if ($fp) {
+ fputs($fp, "[$ts] $msg\n");
+ fclose($fp);
+ }
+ }
+
} // function _debug
/**
@@ -286,11 +291,16 @@
global $fetch_last_error;
if (function_exists('curl_init') && !ini_get("open_basedir")) {
- $ch = curl_init($url);
+
+ if (ini_get("safe_mode")) {
+ $ch = curl_init(geturl($url));
+ } else {
+ $ch = curl_init($url);
+ }
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout ? $timeout : 15);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout ? $timeout : 45);
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, !ini_get("safe_mode"));
curl_setopt($ch, CURLOPT_MAXREDIRS, 20);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
@@ -350,6 +360,9 @@
$data = @file_get_contents($url);
+ @$gzdecoded = gzdecode($data);
+ if ($gzdecoded) $data = $gzdecoded;
+
if (!$data && function_exists('error_get_last')) {
$error = error_get_last();
$fetch_last_error = $error["message"];
@@ -459,6 +472,8 @@
else
$sel = "";
+ $v = trim($v);
+
print "<option value=\"$v\" $sel>$v</option>";
}
print "</select>";
@@ -472,6 +487,8 @@
else
$sel = "";
+ $v = trim($v);
+
print "<option $sel value=\"$v\">".$values[$v]."</option>";
}
@@ -500,7 +517,7 @@
function initialize_user_prefs($link, $uid, $profile = false) {
- $uid = db_escape_string($uid);
+ $uid = db_escape_string($link, $uid);
if (!$profile) {
$profile = "NULL";
@@ -730,7 +747,7 @@
}
}
- function login_sequence($link, $login_form = 0) {
+ function login_sequence($link) {
$_SESSION["prefs_cache"] = false;
if (SINGLE_USER_MODE) {
@@ -746,12 +763,13 @@
authenticate_user($link, null, null, true);
}
- if (!$_SESSION["uid"]) render_login_form($link, $login_form);
+ if (!$_SESSION["uid"]) render_login_form($link);
} else {
/* bump login timestamp */
db_query($link, "UPDATE ttrss_users SET last_login = NOW() WHERE id = " .
$_SESSION["uid"]);
+ $_SESSION["last_login_update"] = time();
}
if ($_SESSION["uid"] && $_SESSION["language"] && SESSION_COOKIE_LIFETIME > 0) {
@@ -762,7 +780,21 @@
if ($_SESSION["uid"]) {
cache_prefs($link);
load_user_plugins($link, $_SESSION["uid"]);
+
+ /* cleanup ccache */
+
+ db_query($link, "DELETE FROM ttrss_counters_cache WHERE owner_uid = ".
+ $_SESSION["uid"] . " AND
+ (SELECT COUNT(id) FROM ttrss_feeds WHERE
+ ttrss_feeds.id = feed_id) = 0");
+
+ db_query($link, "DELETE FROM ttrss_cat_counters_cache WHERE owner_uid = ".
+ $_SESSION["uid"] . " AND
+ (SELECT COUNT(id) FROM ttrss_feed_categories WHERE
+ ttrss_feed_categories.id = feed_id) = 0");
+
}
+
}
}
@@ -774,11 +806,6 @@
}
}
- // Deprecated, TODO: remove
- function theme_image($link, $filename) {
- return $filename;
- }
-
function convert_timestamp($timestamp, $source_tz, $dest_tz) {
try {
@@ -852,7 +879,7 @@
}
function sql_bool_to_bool($s) {
- if ($s == "t" || $s == "1" || $s == "true") {
+ if ($s == "t" || $s == "1" || strtolower($s) == "true") {
return true;
} else {
return false;
@@ -900,7 +927,7 @@
}
}
- if (db_escape_string("testTEST") != "testTEST") {
+ if (db_escape_string($link, "testTEST") != "testTEST") {
$error_code = 12;
}
@@ -1075,7 +1102,7 @@
} else { // tag
db_query($link, "BEGIN");
- $tag_name = db_escape_string($feed);
+ $tag_name = db_escape_string($link, $feed);
$result = db_query($link, "SELECT post_int_id FROM ttrss_tags
WHERE tag_name = '$tag_name' AND owner_uid = $owner_uid");
@@ -1272,7 +1299,7 @@
return 0;
} else if ($feed != "0" && $n_feed == 0) {
- $feed = db_escape_string($feed);
+ $feed = db_escape_string($link, $feed);
$result = db_query($link, "SELECT SUM((SELECT COUNT(int_id)
FROM ttrss_user_entries,ttrss_entries WHERE int_id = post_int_id
@@ -1508,7 +1535,7 @@
* 5 - Couldn't download the URL content.
*/
function subscribe_to_feed($link, $url, $cat_id = 0,
- $auth_login = '', $auth_pass = '', $need_auth = false) {
+ $auth_login = '', $auth_pass = '') {
global $fetch_last_error;
@@ -1813,11 +1840,6 @@
function make_init_params($link) {
$params = array();
- $params["sign_progress"] = theme_image($link, "images/indicator_white.gif");
- $params["sign_progress_tiny"] = theme_image($link, "images/indicator_tiny.gif");
- $params["sign_excl"] = theme_image($link, "images/sign_excl.svg");
- $params["sign_info"] = theme_image($link, "images/sign_info.svg");
-
foreach (array("ON_CATCHUP_SHOW_NEXT_FEED", "HIDE_READ_FEEDS",
"ENABLE_FEED_CATS", "FEEDS_SORT_BY_UNREAD", "CONFIRM_FEED_CATCHUP",
"CDM_AUTO_CATCHUP", "FRESH_ARTICLE_MAX_AGE", "DEFAULT_ARTICLE_LIMIT",
@@ -1877,8 +1899,9 @@
"article_scroll_up" => __("Scroll up"),
"select_article_cursor" => __("Select article under cursor"),
"email_article" => __("Email article"),
- "close_article" => __("Close article"),
- "toggle_widescreen" => __("Toggle widescreen mode")),
+ "close_article" => __("Close/collapse article"),
+ "toggle_widescreen" => __("Toggle widescreen mode"),
+ "toggle_embed_original" => __("Toggle embed original")),
__("Article selection") => array(
"select_all" => __("Select all articles"),
"select_unread" => __("Select unread"),
@@ -1928,23 +1951,26 @@
"(191)|/" => "search_dialog",
// "article" => array(
"s" => "toggle_mark",
- "S" => "toggle_publ",
+ "*s" => "toggle_publ",
"u" => "toggle_unread",
- "T" => "edit_tags",
- "D" => "dismiss_selected",
- "X" => "dismiss_read",
+ "*t" => "edit_tags",
+ "*d" => "dismiss_selected",
+ "*x" => "dismiss_read",
"o" => "open_in_new_window",
"c p" => "catchup_below",
"c n" => "catchup_above",
- "N" => "article_scroll_down",
- "P" => "article_scroll_up",
- "a W" => "toggle_widescreen",
+ "*n" => "article_scroll_down",
+ "*p" => "article_scroll_up",
+ "*(38)|Shift+up" => "article_scroll_up",
+ "*(40)|Shift+down" => "article_scroll_down",
+ "a *w" => "toggle_widescreen",
+ "a e" => "toggle_embed_original",
"e" => "email_article",
"a q" => "close_article",
// "article_selection" => array(
"a a" => "select_all",
"a u" => "select_unread",
- "a U" => "select_marked",
+ "a *u" => "select_marked",
"a p" => "select_published",
"a i" => "select_invert",
"a n" => "select_none",
@@ -1955,9 +1981,9 @@
"f e" => "feed_edit",
"f q" => "feed_catchup",
"f x" => "feed_reverse",
- "f D" => "feed_debug_update",
- "f C" => "toggle_combined_mode",
- "Q" => "catchup_all",
+ "f *d" => "feed_debug_update",
+ "f *c" => "toggle_combined_mode",
+ "*q" => "catchup_all",
"x" => "cat_toggle_collapse",
// "goto" => array(
"g a" => "goto_all",
@@ -1965,7 +1991,7 @@
"g s" => "goto_marked",
"g p" => "goto_published",
"g t" => "goto_tagcloud",
- "g P" => "goto_prefs",
+ "g *p" => "goto_prefs",
// "other" => array(
"(9)|Tab" => "select_article_cursor", // tab
"c l" => "create_label",
@@ -2012,6 +2038,9 @@
$data['last_article_id'] = getLastArticleId($link);
$data['cdm_expanded'] = get_pref($link, 'CDM_EXPANDED');
+ $data['dep_ts'] = calculate_dep_timestamp();
+ $data['reload_on_ts_change'] = !defined('_NO_RELOAD_ON_TS_CHANGE');
+
if (file_exists(LOCK_DIRECTORY . "/update_daemon.lock")) {
$data['daemon_is_running'] = (int) file_is_locked("update_daemon.lock");
@@ -2051,7 +2080,7 @@
return $data;
}
- function search_to_sql($link, $search, $match_on) {
+ function search_to_sql($link, $search) {
$search_query_part = "";
@@ -2098,13 +2127,9 @@
//$k = date("Y-m-d", strtotime(substr($k, 1)));
array_push($query_keywords, "(".SUBSTRING_FOR_DATE."(updated,1,LENGTH('$k')) $not = '$k')");
- } else if ($match_on == "both") {
+ } else {
array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
OR UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))");
- } else if ($match_on == "title") {
- array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%'))");
- } else if ($match_on == "content") {
- array_push($query_keywords, "(UPPER(ttrss_entries.content) $not LIKE UPPER('%$k%'))");
}
}
@@ -2141,7 +2166,7 @@
return $rv;
}
- function queryFeedHeadlines($link, $feed, $limit, $view_mode, $cat_view, $search, $search_mode, $match_on, $override_order = false, $offset = 0, $owner_uid = 0, $filter = false, $since_id = 0, $include_children = false, $ignore_vfeed_group = false) {
+ function queryFeedHeadlines($link, $feed, $limit, $view_mode, $cat_view, $search, $search_mode, $override_order = false, $offset = 0, $owner_uid = 0, $filter = false, $since_id = 0, $include_children = false, $ignore_vfeed_group = false) {
if (!$owner_uid) $owner_uid = $_SESSION["uid"];
@@ -2158,7 +2183,7 @@
$search_query_part = "ref_id = -1 AND ";
} else {
- $search_query_part = search_to_sql($link, $search, $match_on);
+ $search_query_part = search_to_sql($link, $search);
$search_query_part .= " AND ";
}
@@ -2211,14 +2236,15 @@
if ($search) {
$view_query_part = " ";
} else if ($feed != -1) {
+
$unread = getFeedUnread($link, $feed, $cat_view);
if ($cat_view && $feed > 0 && $include_children)
$unread += getCategoryChildrenUnread($link, $feed);
- if ($unread > 0) {
- $view_query_part = " unread = true AND ";
- }
+ if ($unread > 0)
+ $view_query_part = " unread = true AND ";
+
}
}
@@ -2230,7 +2256,7 @@
$view_query_part = " published = true AND ";
}
- if ($view_mode == "unread") {
+ if ($view_mode == "unread" && $feed != -6) {
$view_query_part = " unread = true AND ";
}
@@ -2310,6 +2336,14 @@
$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
$allow_archived = true;
+ if (!$override_order) {
+ if (get_pref($link, 'REVERSE_HEADLINES', $owner_uid)) {
+ $override_order = "date_entered";
+ } else {
+ $override_order = "last_marked DESC, date_entered DESC";
+ }
+ }
+
} else if ($feed == -2) { // published virtual feed OR labels category
if (!$cat_view) {
@@ -2317,7 +2351,14 @@
$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
$allow_archived = true;
- if (!$override_order) $override_order = "last_read DESC, updated DESC";
+ if (!$override_order) {
+ if (get_pref($link, 'REVERSE_HEADLINES', $owner_uid)) {
+ $override_order = "date_entered";
+ } else {
+ $override_order = "last_published DESC, date_entered DESC";
+ }
+ }
+
} else {
$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
@@ -2379,6 +2420,10 @@
$order_by = "score DESC, $order_by";
}
+ if ($view_mode == "unread_first") {
+ $order_by = "unread DESC, $order_by";
+ }
+
if ($override_order) {
$order_by = $override_order;
}
@@ -2449,7 +2494,9 @@
num_comments,
comments,
int_id,
+ hide_images,
unread,feed_id,marked,published,link,last_read,orig_feed_id,
+ last_marked, last_published,
".SUBSTRING_FOR_DATE."(last_read,1,19) as last_read_noms,
$vfeed_query_part
$content_query_part
@@ -2492,6 +2539,8 @@
"label_cache," .
"link," .
"last_read," .
+ "(SELECT hide_images FROM ttrss_feeds WHERE id = feed_id) AS hide_images," .
+ "last_marked, last_published, " .
SUBSTRING_FOR_DATE . "(last_read,1,19) as last_read_noms," .
$since_id_part .
$vfeed_query_part .
@@ -2546,19 +2595,11 @@
}
- function sanitize($link, $str, $force_strip_tags = false, $owner = false, $site_url = false) {
+ function sanitize($link, $str, $force_remove_images = false, $owner = false, $site_url = false) {
if (!$owner) $owner = $_SESSION["uid"];
$res = trim($str); if (!$res) return '';
- $config = array('safe' => 1, 'deny_attribute' => 'style, width, height, class, id', 'comment' => 1, 'cdata' => 1, 'balance' => 0);
- $spec = 'img=width,height';
- $res = htmLawed($res, $config, $spec);
-
- if (get_pref($link, "STRIP_IMAGES", $owner)) {
- $res = preg_replace('/<img[^>]+>/is', '', $res);
- }
-
if (strpos($res, "href=") === false)
$res = rewrite_urls($res);
@@ -2584,10 +2625,35 @@
$entry->setAttribute('href',
rewrite_relative_url($site_url, $entry->getAttribute('href')));
- if ($entry->hasAttribute('src'))
- if (preg_match('/^image.php\?i=[a-z0-9]+$/', $entry->getAttribute('src')) == 0)
- $entry->setAttribute('src',
- rewrite_relative_url($site_url, $entry->getAttribute('src')));
+ if ($entry->hasAttribute('src')) {
+ $src = rewrite_relative_url($site_url, $entry->getAttribute('src'));
+
+ $cached_filename = CACHE_DIR . '/images/' . sha1($src) . '.png';
+
+ if (file_exists($cached_filename)) {
+ $src = SELF_URL_PATH . '/image.php?hash=' . sha1($src);
+ }
+
+ $entry->setAttribute('src', $src);
+ }
+
+ if ($entry->nodeName == 'img') {
+ if (($owner && get_pref($link, "STRIP_IMAGES", $owner)) ||
+ $force_remove_images) {
+
+ $p = $doc->createElement('p');
+
+ $a = $doc->createElement('a');
+ $a->setAttribute('href', $entry->getAttribute('src'));
+
+ $a->appendChild(new DOMText($entry->getAttribute('src')));
+ $a->setAttribute('target', '_blank');
+
+ $p->appendChild($a);
+
+ $entry->parentNode->replaceChild($p, $entry);
+ }
+ }
}
if (strtolower($entry->nodeName) == "a") {
@@ -2595,9 +2661,69 @@
}
}
- $node = $doc->getElementsByTagName('body')->item(0);
+ $entries = $xpath->query('//iframe');
+ foreach ($entries as $entry) {
+ $entry->setAttribute('sandbox', 'allow-scripts');
+
+ }
+
+ global $pluginhost;
+
+ if (isset($pluginhost)) {
+ foreach ($pluginhost->get_hooks($pluginhost::HOOK_SANITIZE) as $plugin) {
+ $doc = $plugin->hook_sanitize($doc, $site_url);
+ }
+ }
+
+ $doc->removeChild($doc->firstChild); //remove doctype
+ $doc = strip_harmful_tags($doc);
+ $res = $doc->saveHTML();
+ return $res;
+ }
+
+ function strip_harmful_tags($doc) {
+ $entries = $doc->getElementsByTagName("*");
+
+ $allowed_elements = array('a', 'address', 'audio', 'article',
+ 'b', 'big', 'blockquote', 'body', 'br', 'cite', 'center',
+ 'code', 'dd', 'del', 'details', 'div', 'dl', 'font',
+ 'dt', 'em', 'footer', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
+ 'header', 'html', 'i', 'img', 'ins', 'kbd',
+ 'li', 'nav', 'ol', 'p', 'pre', 'q', 's','small',
+ 'source', 'span', 'strike', 'strong', 'sub', 'summary',
+ 'sup', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead',
+ 'tr', 'track', 'tt', 'u', 'ul', 'var', 'wbr', 'video' );
+
+ if ($_SESSION['hasSandbox']) array_push($allowed_elements, 'iframe');
+
+ $disallowed_attributes = array('id', 'style', 'class');
+
+ foreach ($entries as $entry) {
+ if (!in_array($entry->nodeName, $allowed_elements)) {
+ $entry->parentNode->removeChild($entry);
+ }
+
+ if ($entry->hasAttributes()) {
+ $attrs_to_remove = array();
+
+ foreach ($entry->attributes as $attr) {
+
+ if (strpos($attr->nodeName, 'on') === 0) {
+ array_push($attrs_to_remove, $attr);
+ }
+
+ if (in_array($attr->nodeName, $disallowed_attributes)) {
+ array_push($attrs_to_remove, $attr);
+ }
+ }
+
+ foreach ($attrs_to_remove as $attr) {
+ $entry->removeAttributeNode($attr);
+ }
+ }
+ }
- return $doc->saveXML($node);
+ return $doc;
}
function check_for_update($link) {
@@ -2659,7 +2785,7 @@
function get_article_tags($link, $id, $owner_uid = 0, $tag_cache = false) {
- $a_id = db_escape_string($id);
+ $a_id = db_escape_string($link, $id);
if (!$owner_uid) $owner_uid = $_SESSION["uid"];
@@ -2694,7 +2820,7 @@
/* update the cache */
- $tags_str = db_escape_string(join(",", $tags));
+ $tags_str = db_escape_string($link, join(",", $tags));
db_query($link, "UPDATE ttrss_user_entries
SET tag_cache = '$tags_str' WHERE ref_id = '$id'
@@ -2724,15 +2850,8 @@
return true;
}
- function render_login_form($link, $form_id = 0) {
- switch ($form_id) {
- case 0:
- require_once "login_form.php";
- break;
- case 1:
- require_once "mobile/login_form.php";
- break;
- }
+ function render_login_form($link) {
+ require_once "login_form.php";
exit;
}
@@ -2748,19 +2867,19 @@
function format_warning($msg, $id = "") {
global $link;
return "<div class=\"warning\" id=\"$id\">
- <img src=\"".theme_image($link, "images/sign_excl.svg")."\">$msg</div>";
+ <img src=\"images/sign_excl.svg\">$msg</div>";
}
function format_notice($msg, $id = "") {
global $link;
return "<div class=\"notice\" id=\"$id\">
- <img src=\"".theme_image($link, "images/sign_info.svg")."\">$msg</div>";
+ <img src=\"images/sign_info.svg\">$msg</div>";
}
function format_error($msg, $id = "") {
global $link;
return "<div class=\"error\" id=\"$id\">
- <img src=\"".theme_image($link, "images/sign_excl.svg")."\">$msg</div>";
+ <img src=\"images/sign_excl.svg\">$msg</div>";
}
function print_notice($msg) {
@@ -2785,6 +2904,8 @@
$entry = "";
+ $url = htmlspecialchars($url);
+
if (strpos($ctype, "audio/") === 0) {
if ($_SESSION["hasAudio"] && (strpos($ctype, "ogg") !== false ||
@@ -2811,7 +2932,8 @@
</object>";
}
- if ($entry) $entry .= "&nbsp;" . basename($url);
+ if ($entry) $entry .= "&nbsp; <a target=\"_blank\"
+ href=\"$url\">" . basename($url) . "</a>";
return $entry;
@@ -2856,6 +2978,7 @@
$result = db_query($link, "SELECT id,title,link,content,feed_id,comments,int_id,
".SUBSTRING_FOR_DATE."(updated,1,16) as updated,
(SELECT site_url FROM ttrss_feeds WHERE id = feed_id) as site_url,
+ (SELECT hide_images FROM ttrss_feeds WHERE id = feed_id) as hide_images,
num_comments,
tag_cache,
author,
@@ -2904,14 +3027,9 @@
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>
<title>Tiny Tiny RSS - ".$line["title"]."</title>
<link rel=\"stylesheet\" type=\"text/css\" href=\"tt-rss.css\">
- </head><body>";
+ </head><body id=\"ttrssZoom\">";
}
- $title_escaped = htmlspecialchars($line['title']);
-
- $rv['content'] .= "<div id=\"PTITLE-FULL-$id\" style=\"display : none\">" .
- strip_tags($line['title']) . "</div>";
-
$rv['content'] .= "<div class=\"postReply\" id=\"POST-$id\">";
$rv['content'] .= "<div class=\"postHeader\" id=\"POSTHDR-$id\">";
@@ -2932,8 +3050,8 @@
title=\"".htmlspecialchars($line['title'])."\"
href=\"" .
htmlspecialchars($line["link"]) . "\">" .
- $line["title"] .
- "<span class='author'>$entry_author</span></a></div>";
+ $line["title"] . "</a>" .
+ "<span class='author'>$entry_author</span></div>";
} else {
$rv['content'] .= "<div class='postTitle'>" . $line["title"] . "$entry_author</div>";
}
@@ -2946,7 +3064,7 @@
if (!$entry_comments) $entry_comments = "&nbsp;"; # placeholder
$rv['content'] .= "<div class='postTags' style='float : right'>
- <img src='".theme_image($link, 'images/tag.png')."'
+ <img src='images/tag.png'
class='tagsPic' alt='Tags' title='Tags'>&nbsp;";
if (!$zoom_mode) {
@@ -3009,35 +3127,10 @@
$rv['content'] .= "<div class=\"postContent\">";
- // N-grams
-
- if (DB_TYPE == "pgsql" and defined('_NGRAM_TITLE_RELATED_THRESHOLD')) {
-
- $ngram_result = db_query($link, "SELECT id,title FROM
- ttrss_entries,ttrss_user_entries
- WHERE ref_id = id AND updated >= NOW() - INTERVAL '7 day'
- AND similarity(title, '$title_escaped') >= "._NGRAM_TITLE_RELATED_THRESHOLD."
- AND title != '$title_escaped'
- AND owner_uid = $owner_uid");
-
- if (db_num_rows($ngram_result) > 0) {
- $rv['content'] .= "<div dojoType=\"dijit.form.DropDownButton\">".
- "<span>" . __('Related')."</span>";
- $rv['content'] .= "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
-
- while ($nline = db_fetch_assoc($ngram_result)) {
- $rv['content'] .= "<div onclick=\"hlOpenInNewTab(null,".$nline['id'].")\"
- dojoType=\"dijit.MenuItem\">".$nline['title']."</div>";
-
- }
- $rv['content'] .= "</div></div><br/";
- }
- }
-
$rv['content'] .= $line["content"];
$rv['content'] .= format_article_enclosures($link, $id,
- $always_display_enclosures, $line["content"]);
+ $always_display_enclosures, $line["content"], $line["hide_images"]);
$rv['content'] .= "</div>";
@@ -3047,7 +3140,7 @@
if ($zoom_mode) {
$rv['content'] .= "
- <div style=\"text-align : center\">
+ <div class='footer'>
<button onclick=\"return window.close()\">".
__("Close this window")."</button></div>";
$rv['content'] .= "</body></html>";
@@ -3124,7 +3217,7 @@
$filter_id = $line["id"];
$result2 = db_query($link, "SELECT
- r.reg_exp, r.feed_id, r.cat_id, r.cat_filter, t.name AS type_name
+ r.reg_exp, r.inverse, r.feed_id, r.cat_id, r.cat_filter, t.name AS type_name
FROM ttrss_filters2_rules AS r,
ttrss_filter_types AS t
WHERE
@@ -3141,6 +3234,7 @@
$rule = array();
$rule["reg_exp"] = $rule_line["reg_exp"];
$rule["type"] = $rule_line["type_name"];
+ $rule["inverse"] = sql_bool_to_bool($rule_line["inverse"]);
array_push($rules, $rule);
}
@@ -3164,6 +3258,7 @@
$filter = array();
$filter["match_any_rule"] = sql_bool_to_bool($line["match_any_rule"]);
+ $filter["inverse"] = sql_bool_to_bool($line["inverse"]);
$filter["rules"] = $rules;
$filter["actions"] = $actions;
@@ -3429,7 +3524,7 @@
if (db_num_rows($result) == 1) {
return db_fetch_result($result, 0, "access_key");
} else {
- $key = db_escape_string(sha1(uniqid(rand(), true)));
+ $key = db_escape_string($link, sha1(uniqid(rand(), true)));
$result = db_query($link, "INSERT INTO ttrss_access_keys
(access_key, feed_id, is_cat, owner_uid)
@@ -3500,7 +3595,7 @@
}
function format_article_enclosures($link, $id, $always_display_enclosures,
- $article_content) {
+ $article_content, $hide_images = false) {
$result = get_article_enclosures($link, $id);
$rv = '';
@@ -3541,7 +3636,7 @@
array_push($entries, $entry);
}
- if (!get_pref($link, "STRIP_IMAGES")) {
+ if ($_SESSION['uid'] && !get_pref($link, "STRIP_IMAGES")) {
if ($always_display_enclosures ||
!preg_match("/<img/i", $article_content)) {
@@ -3550,10 +3645,16 @@
if (preg_match("/image/", $entry["type"]) ||
preg_match("/\.(jpg|png|gif|bmp)/i", $entry["filename"])) {
- $rv .= "<p><img
- alt=\"".htmlspecialchars($entry["filename"])."\"
- src=\"" .htmlspecialchars($entry["url"]) . "\"/></p>";
+ if (!$hide_images) {
+ $rv .= "<p><img
+ alt=\"".htmlspecialchars($entry["filename"])."\"
+ src=\"" .htmlspecialchars($entry["url"]) . "\"/></p>";
+ } else {
+ $rv .= "<p><a target=\"_blank\"
+ href=\"".htmlspecialchars($entry["url"])."\"
+ >" .htmlspecialchars($entry["url"]) . "</a></p>";
+ }
}
}
}
@@ -3777,9 +3878,9 @@
if ($regexp_valid) {
- $rule['reg_exp'] = db_escape_string($rule['reg_exp']);
+ $rule['reg_exp'] = db_escape_string($link, $rule['reg_exp']);
- switch ($rule["type"]) {
+ switch ($rule["type"]) {
case "title":
$qpart = "LOWER(ttrss_entries.title) $reg_qpart LOWER('".
$rule['reg_exp'] . "')";
@@ -3807,8 +3908,10 @@
break;
}
+ if (isset($rule['inverse'])) $qpart = "NOT ($qpart)";
+
if (isset($rule["feed_id"]) && $rule["feed_id"] > 0) {
- $qpart .= " AND feed_id = " . db_escape_string($rule["feed_id"]);
+ $qpart .= " AND feed_id = " . db_escape_string($link, $rule["feed_id"]);
}
if (isset($rule["cat_id"])) {
@@ -3833,10 +3936,14 @@
}
if (count($query) > 0) {
- return "(" . join($filter["match_any_rule"] ? "OR" : "AND", $query) . ")";
+ $fullquery = "(" . join($filter["match_any_rule"] ? "OR" : "AND", $query) . ")";
} else {
- return "(false)";
+ $fullquery = "(false)";
}
+
+ if ($filter['inverse']) $fullquery = "(NOT $fullquery)";
+
+ return $fullquery;
}
if (!function_exists('gzdecode')) {
@@ -3900,4 +4007,152 @@
return in_array($interface, class_implements($class));
}
+ function geturl($url){
+
+ (function_exists('curl_init')) ? '' : die('cURL Must be installed for geturl function to work. Ask your host to enable it or uncomment extension=php_curl.dll in php.ini');
+
+ $curl = curl_init();
+ $header[0] = "Accept: text/xml,application/xml,application/xhtml+xml,";
+ $header[0] .= "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
+ $header[] = "Cache-Control: max-age=0";
+ $header[] = "Connection: keep-alive";
+ $header[] = "Keep-Alive: 300";
+ $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
+ $header[] = "Accept-Language: en-us,en;q=0.5";
+ $header[] = "Pragma: ";
+
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0 Firefox/5.0');
+ curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
+ curl_setopt($curl, CURLOPT_HEADER, true);
+ curl_setopt($curl, CURLOPT_REFERER, $url);
+ curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
+ curl_setopt($curl, CURLOPT_AUTOREFERER, true);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); //CURLOPT_FOLLOWLOCATION Disabled...
+ curl_setopt($curl, CURLOPT_TIMEOUT, 60);
+
+ $html = curl_exec($curl);
+
+ $status = curl_getinfo($curl);
+ curl_close($curl);
+
+ if($status['http_code']!=200){
+ if($status['http_code'] == 301 || $status['http_code'] == 302) {
+ list($header) = explode("\r\n\r\n", $html, 2);
+ $matches = array();
+ preg_match("/(Location:|URI:)[^(\n)]*/", $header, $matches);
+ $url = trim(str_replace($matches[1],"",$matches[0]));
+ $url_parsed = parse_url($url);
+ return (isset($url_parsed))? geturl($url, $referer):'';
+ }
+ $oline='';
+ foreach($status as $key=>$eline){$oline.='['.$key.']'.$eline.' ';}
+ $line =$oline." \r\n ".$url."\r\n-----------------\r\n";
+# $handle = @fopen('./curl.error.log', 'a');
+# fwrite($handle, $line);
+ return FALSE;
+ }
+ return $url;
+ }
+
+ function get_minified_js($files) {
+ require_once 'lib/jshrink/Minifier.php';
+
+ $rv = '';
+
+ foreach ($files as $js) {
+ if (!isset($_GET['debug'])) {
+ $cached_file = CACHE_DIR . "/js/$js.js";
+
+ if (file_exists($cached_file) &&
+ is_readable($cached_file) &&
+ filemtime($cached_file) >= filemtime("js/$js.js")) {
+
+ $rv .= file_get_contents($cached_file);
+
+ } else {
+ $minified = JShrink\Minifier::minify(file_get_contents("js/$js.js"));
+ file_put_contents($cached_file, $minified);
+ $rv .= $minified;
+ }
+ } else {
+ $rv .= file_get_contents("js/$js.js");
+ }
+ }
+
+ return $rv;
+ }
+
+ function stylesheet_tag($filename) {
+ $timestamp = filemtime($filename);
+
+ echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"$filename?$timestamp\"/>\n";
+ }
+
+ function javascript_tag($filename) {
+ $query = "";
+
+ if (!(strpos($filename, "?") === FALSE)) {
+ $query = substr($filename, strpos($filename, "?")+1);
+ $filename = substr($filename, 0, strpos($filename, "?"));
+ }
+
+ $timestamp = filemtime($filename);
+
+ if ($query) $timestamp .= "&$query";
+
+ echo "<script type=\"text/javascript\" charset=\"utf-8\" src=\"$filename?$timestamp\"></script>\n";
+ }
+
+ function calculate_dep_timestamp() {
+ $files = array_merge(glob("js/*.js"), glob("*.css"));
+
+ $max_ts = -1;
+
+ foreach ($files as $file) {
+ if (filemtime($file) > $max_ts) $max_ts = filemtime($file);
+ }
+
+ return $max_ts;
+ }
+
+ function T_js_decl($s1, $s2) {
+ if ($s1 && $s2) {
+ $s1 = preg_replace("/\n/", "", $s1);
+ $s2 = preg_replace("/\n/", "", $s2);
+
+ $s1 = preg_replace("/\"/", "\\\"", $s1);
+ $s2 = preg_replace("/\"/", "\\\"", $s2);
+
+ return "T_messages[\"$s1\"] = \"$s2\";\n";
+ }
+ }
+
+ function init_js_translations() {
+
+ print 'var T_messages = new Object();
+
+ function __(msg) {
+ if (T_messages[msg]) {
+ return T_messages[msg];
+ } else {
+ return msg;
+ }
+ }
+
+ function ngettext(msg1, msg2, n) {
+ return (parseInt(n) > 1) ? msg2 : msg1;
+ }';
+
+ $l10n = _get_reader();
+
+ for ($i = 0; $i < $l10n->total; $i++) {
+ $orig = $l10n->get_original_string($i);
+ $translation = __($orig);
+
+ print T_js_decl($orig, $translation);
+ }
+ }
+
?>
diff --git a/include/labels.php b/include/labels.php
index da7e3f97b..75936007e 100644
--- a/include/labels.php
+++ b/include/labels.php
@@ -88,7 +88,7 @@
if (!$labels)
$labels = get_article_labels($link, $id);
- $labels = db_escape_string(json_encode($labels));
+ $labels = db_escape_string($link, json_encode($labels));
db_query($link, "UPDATE ttrss_user_entries SET
label_cache = '$labels' WHERE ref_id = '$id' AND owner_uid = '$owner_uid'");
@@ -163,13 +163,6 @@
db_query($link, "DELETE FROM ttrss_access_keys WHERE
feed_id = '$ext_id' AND owner_uid = $owner_uid");
- /* Disable filters that reference label being removed */
-
- db_query($link, "UPDATE ttrss_filters SET
- enabled = false WHERE action_param = '$caption'
- AND action_id = 7
- AND owner_uid = " . $owner_uid);
-
/* Remove cached data */
db_query($link, "UPDATE ttrss_user_entries SET label_cache = ''
diff --git a/include/localized_schema.php b/include/localized_schema.php
index 3497c9c27..b3a5b3a16 100644
--- a/include/localized_schema.php
+++ b/include/localized_schema.php
@@ -1,4 +1,4 @@
-<?php # This file has been generated at: Sun Feb 17 13:58:53 MSK 2013
+<?php # This file has been generated at: Mon Mar 25 12:27:33 MSK 2013
__("Title");
__("Title or Content");
@@ -54,7 +54,7 @@ __('Automatically expand articles in combined mode');
__('Purge unread articles');
__('Show special feeds when hiding read feeds');
__('Group headlines in virtual feeds');
-__('Do not show images in articles');
+__('Do not embed images in articles');
__('Enable external API');
__('User timezone');
__('Customize stylesheet');
diff --git a/include/login_form.php b/include/login_form.php
index 68df544e3..af451239d 100644
--- a/include/login_form.php
+++ b/include/login_form.php
@@ -65,6 +65,20 @@
font-size : 12px;
}
+ a.forgotpass {
+ text-align : right;
+ font-size : 11px;
+ display : inline-block;
+ }
+
+ a {
+ color : #4684ff;
+ }
+
+ a:hover {
+ color : black;
+ }
+
div.footer a {
color : gray;
}
@@ -179,6 +193,8 @@ function bwLimitChange(elem) {
<input type="password" name="password" required="1"
style="width : 220px" class="input"
value="<?php echo $_SESSION["fake_password"] ?>"/>
+ <label></label>
+ <a class='forgotpass' href="public.php?op=forgotpass"><?php echo __("I forgot my password") ?></a>
</div>
<div class="row">
diff --git a/include/rssfuncs.php b/include/rssfuncs.php
index 5c49008c5..130f9142c 100644
--- a/include/rssfuncs.php
+++ b/include/rssfuncs.php
@@ -18,10 +18,10 @@
$count = 0;
while ($line = db_fetch_assoc($result)) {
- $subscribers = db_escape_string($line["subscribers"]);
- $feed_url = db_escape_string($line["feed_url"]);
- $title = db_escape_string($line["title"]);
- $site_url = db_escape_string($line["site_url"]);
+ $subscribers = db_escape_string($link, $line["subscribers"]);
+ $feed_url = db_escape_string($link, $line["feed_url"]);
+ $title = db_escape_string($link, $line["title"]);
+ $site_url = db_escape_string($link, $line["site_url"]);
$tmp_result = db_query($link, "SELECT subscribers FROM
ttrss_feedbrowser_cache WHERE feed_url = '$feed_url'");
@@ -200,7 +200,7 @@
$cache_images = sql_bool_to_bool(db_fetch_result($result, 0, "cache_images"));
$fetch_url = db_fetch_result($result, 0, "feed_url");
- $feed = db_escape_string($feed);
+ $feed = db_escape_string($link, $feed);
/* if ($auth_login && $auth_pass ){
$url_parts = array();
@@ -238,7 +238,7 @@
_debug("update_rss_feed: unable to fetch: $fetch_last_error");
}
- $error_escaped = db_escape_string($fetch_last_error);
+ $error_escaped = db_escape_string($link, $fetch_last_error);
db_query($link,
"UPDATE ttrss_feeds SET last_error = '$error_escaped',
@@ -287,7 +287,7 @@
// print_r($rss);
- $feed = db_escape_string($feed);
+ $feed = db_escape_string($link, $feed);
if (!$rss->error()) {
@@ -318,7 +318,7 @@
$owner_uid = db_fetch_result($result, 0, "owner_uid");
- $site_url = db_escape_string(mb_substr(rewrite_relative_url($fetch_url, $rss->get_link()), 0, 245));
+ $site_url = db_escape_string($link, mb_substr(rewrite_relative_url($fetch_url, $rss->get_link()), 0, 245));
if ($debug_enabled) {
_debug("update_rss_feed: checking favicon...");
@@ -333,7 +333,7 @@
if (!$registered_title || $registered_title == "[Unknown]") {
- $feed_title = db_escape_string($rss->get_title());
+ $feed_title = db_escape_string($link, $rss->get_title());
if ($debug_enabled) {
_debug("update_rss_feed: registering title: $feed_title");
@@ -435,7 +435,7 @@
$entry_timestamp = strtotime($item->get_date());
- if ($entry_timestamp == -1 || !$entry_timestamp) {
+ if ($entry_timestamp == -1 || !$entry_timestamp || $entry_timestamp > time()) {
$entry_timestamp = time();
$no_orig_date = 'true';
} else {
@@ -475,13 +475,13 @@
$entry_author = $entry_author_item->get_name();
if (!$entry_author) $entry_author = $entry_author_item->get_email();
- $entry_author = db_escape_string($entry_author);
+ $entry_author = db_escape_string($link, $entry_author);
}
- $entry_guid = db_escape_string(mb_substr($entry_guid, 0, 245));
+ $entry_guid = db_escape_string($link, mb_substr($entry_guid, 0, 245));
- $entry_comments = db_escape_string(mb_substr($entry_comments, 0, 245));
- $entry_author = db_escape_string(mb_substr($entry_author, 0, 245));
+ $entry_comments = db_escape_string($link, mb_substr($entry_comments, 0, 245));
+ $entry_author = db_escape_string($link, mb_substr($entry_author, 0, 245));
$num_comments = $item->get_item_tags('http://purl.org/rss/1.0/modules/slash/', 'comments');
@@ -539,7 +539,7 @@
// FIXME not sure if owner_uid is a good idea here, we may have a base entry without user entry (?)
$result = db_query($link, "SELECT plugin_data,title,content,link,tag_cache,author FROM ttrss_entries, ttrss_user_entries
- WHERE ref_id = id AND guid = '".db_escape_string($entry_guid)."' AND owner_uid = $owner_uid");
+ WHERE ref_id = id AND guid = '".db_escape_string($link, $entry_guid)."' AND owner_uid = $owner_uid");
if (db_num_rows($result) != 0) {
$entry_plugin_data = db_fetch_result($result, 0, "plugin_data");
@@ -568,20 +568,22 @@
}
$entry_tags = $article["tags"];
- $entry_guid = db_escape_string($entry_guid);
- $entry_title = db_escape_string($article["title"]);
- $entry_author = db_escape_string($article["author"]);
- $entry_link = db_escape_string($article["link"]);
- $entry_plugin_data = db_escape_string($article["plugin_data"]);
+ $entry_guid = db_escape_string($link, $entry_guid);
+ $entry_title = db_escape_string($link, $article["title"]);
+ $entry_author = db_escape_string($link, $article["author"]);
+ $entry_link = db_escape_string($link, $article["link"]);
+ $entry_plugin_data = db_escape_string($link, $article["plugin_data"]);
+ $entry_content = $article["content"]; // escaped below
+
if ($debug_enabled) {
_debug("update_rss_feed: plugin data: $entry_plugin_data");
}
if ($cache_images && is_writable(CACHE_DIR . '/images'))
- $entry_content = cache_images($entry_content, $site_url, $debug_enabled);
+ cache_images($entry_content, $site_url, $debug_enabled);
- $entry_content = db_escape_string($article["content"], false);
+ $entry_content = db_escape_string($link, $entry_content, false);
$content_hash = "SHA1:" . sha1($entry_content);
@@ -766,12 +768,17 @@
}
}
+ $last_marked = ($marked == 'true') ? 'NOW()' : 'NULL';
+ $last_published = ($published == 'true') ? 'NOW()' : 'NULL';
+
$result = db_query($link,
"INSERT INTO ttrss_user_entries
(ref_id, owner_uid, feed_id, unread, last_read, marked,
- published, score, tag_cache, label_cache, uuid)
+ published, score, tag_cache, label_cache, uuid,
+ last_marked, last_published)
VALUES ('$ref_id', '$owner_uid', '$feed', $unread,
- $last_read_qpart, $marked, $published, '$score', '', '', '')");
+ $last_read_qpart, $marked, $published, '$score', '', '',
+ '', $last_marked, $last_published)");
if (PUBSUBHUBBUB_HUB && $published == 'true') {
$rss_link = get_self_url_prefix() .
@@ -822,7 +829,7 @@
$update_insignificant = false;
}
- if (db_escape_string($orig_title) != $entry_title) {
+ if (db_escape_string($link, $orig_title) != $entry_title) {
$post_needs_update = true;
$update_insignificant = false;
}
@@ -889,9 +896,9 @@
db_query($link, "BEGIN");
foreach ($enclosures as $enc) {
- $enc_url = db_escape_string($enc[0]);
- $enc_type = db_escape_string($enc[1]);
- $enc_dur = db_escape_string($enc[2]);
+ $enc_url = db_escape_string($link, $enc[0]);
+ $enc_type = db_escape_string($link, $enc[1]);
+ $enc_dur = db_escape_string($link, $enc[2]);
$result = db_query($link, "SELECT id FROM ttrss_enclosures
WHERE content_url = '$enc_url' AND post_id = '$entry_ref_id'");
@@ -952,7 +959,7 @@
foreach ($filtered_tags as $tag) {
$tag = sanitize_tag($tag);
- $tag = db_escape_string($tag);
+ $tag = db_escape_string($link, $tag);
if (!tag_is_valid($tag)) continue;
@@ -974,7 +981,7 @@
$tags_to_cache = array_unique($tags_to_cache);
- $tags_str = db_escape_string(join(",", $tags_to_cache));
+ $tags_str = db_escape_string($link, join(",", $tags_to_cache));
db_query($link, "UPDATE ttrss_user_entries
SET tag_cache = '$tags_str' WHERE ref_id = '$entry_ref_id'
@@ -989,9 +996,9 @@
}
foreach ($labels as $label) {
- $caption = $label["caption"];
+ $caption = preg_quote($label["caption"]);
- if (preg_match("/\b$caption\b/i", "$tags_str " . strip_tags($entry_content) . " $entry_title")) {
+ if ($caption && preg_match("/\b$caption\b/i", "$tags_str " . strip_tags($entry_content) . " $entry_title")) {
if (!labels_contains_caption($article_labels, $caption)) {
label_add_article($link, $entry_ref_id, $caption, $owner_uid);
}
@@ -1024,7 +1031,7 @@
} else {
- $error_msg = db_escape_string(mb_substr($rss->error(), 0, 245));
+ $error_msg = db_escape_string($link, mb_substr($rss->error(), 0, 245));
if ($debug_enabled) {
_debug("update_rss_feed: error fetching feed: $error_msg");
@@ -1158,11 +1165,13 @@
foreach ($filters as $filter) {
$match_any_rule = $filter["match_any_rule"];
+ $inverse = $filter["inverse"];
$filter_match = false;
foreach ($filter["rules"] as $rule) {
$match = false;
$reg_exp = $rule["reg_exp"];
+ $rule_inverse = $rule["inverse"];
if (!$reg_exp)
continue;
@@ -1195,6 +1204,8 @@
break;
}
+ if ($rule_inverse) $match = !$match;
+
if ($match_any_rule) {
if ($match) {
$filter_match = true;
@@ -1208,6 +1219,8 @@
}
}
+ if ($inverse) $filter_match = !$filter_match;
+
if ($filter_match) {
foreach ($filter["actions"] AS $action) {
array_push($matches, $action);
diff --git a/include/sanity_check.php b/include/sanity_check.php
index 5cb556746..0373196b3 100644
--- a/include/sanity_check.php
+++ b/include/sanity_check.php
@@ -36,6 +36,10 @@
array_push($errors, "Data export cache is not writable (chmod -R 777 ".CACHE_DIR."/export)");
}
+ if (!is_writable(CACHE_DIR . "/js")) {
+ array_push($errors, "Javascript cache is not writable (chmod -R 777 ".CACHE_DIR."/js)");
+ }
+
if (GENERATED_CONFIG_CHECK != EXPECTED_CONFIG_VERSION) {
array_push($errors,
"Configuration option checker sanity_config.php is outdated, please recreate it using ./utils/regen_config_checks.sh");
@@ -117,10 +121,14 @@
array_push($errors, "PHP support for ctype functions are required by HTMLPurifier.");
}
- if (ini_get("safe_mode")) {
- array_push($errors, "PHP safe mode setting is not supported.");
+ if (!function_exists("iconv")) {
+ array_push($errors, "PHP support for iconv is required to handle multiple charsets.");
}
+ /* if (ini_get("safe_mode")) {
+ array_push($errors, "PHP safe mode setting is not supported.");
+ } */
+
if ((PUBSUBHUBBUB_HUB || PUBSUBHUBBUB_ENABLED) && !function_exists("curl_init")) {
array_push($errors, "PHP support for CURL is required for PubSubHubbub.");
}
diff --git a/include/sanity_config.php b/include/sanity_config.php
index d4a468f6d..80be1434e 100644
--- a/include/sanity_config.php
+++ b/include/sanity_config.php
@@ -1,3 +1,3 @@
<?php # This file has been generated at: Sat Feb 9 22:34:30 MSK 2013
define('GENERATED_CONFIG_CHECK', 26);
-$requred_defines = array( 'DB_TYPE', 'DB_HOST', 'DB_USER', 'DB_NAME', 'DB_PASS', 'MYSQL_CHARSET', 'SELF_URL_PATH', 'SINGLE_USER_MODE', 'SIMPLE_UPDATE_MODE', 'PHP_EXECUTABLE', 'LOCK_DIRECTORY', 'CACHE_DIR', 'ICONS_DIR', 'ICONS_URL', 'AUTH_AUTO_CREATE', 'AUTH_AUTO_LOGIN', 'FORCE_ARTICLE_PURGE', 'PUBSUBHUBBUB_HUB', 'PUBSUBHUBBUB_ENABLED', 'SPHINX_ENABLED', 'SPHINX_INDEX', 'ENABLE_REGISTRATION', 'REG_NOTIFY_ADDRESS', 'REG_MAX_USERS', 'SESSION_COOKIE_LIFETIME', 'SESSION_EXPIRE_TIME', 'SESSION_CHECK_ADDRESS', 'SMTP_FROM_NAME', 'SMTP_FROM_ADDRESS', 'DIGEST_SUBJECT', 'SMTP_HOST', 'SMTP_LOGIN', 'SMTP_PASSWORD', 'CHECK_FOR_NEW_VERSION', 'ENABLE_GZIP_OUTPUT', 'PLUGINS', 'CONFIG_VERSION'); ?>
+$requred_defines = array( 'DB_TYPE', 'DB_HOST', 'DB_USER', 'DB_NAME', 'DB_PASS', 'MYSQL_CHARSET', 'SELF_URL_PATH', 'SINGLE_USER_MODE', 'SIMPLE_UPDATE_MODE', 'PHP_EXECUTABLE', 'LOCK_DIRECTORY', 'CACHE_DIR', 'ICONS_DIR', 'ICONS_URL', 'AUTH_AUTO_CREATE', 'AUTH_AUTO_LOGIN', 'FORCE_ARTICLE_PURGE', 'PUBSUBHUBBUB_HUB', 'PUBSUBHUBBUB_ENABLED', 'SPHINX_ENABLED', 'SPHINX_INDEX', 'ENABLE_REGISTRATION', 'REG_NOTIFY_ADDRESS', 'REG_MAX_USERS', 'SESSION_COOKIE_LIFETIME', 'SESSION_EXPIRE_TIME', 'SESSION_CHECK_ADDRESS', 'SMTP_FROM_NAME', 'SMTP_FROM_ADDRESS', 'DIGEST_SUBJECT', 'SMTP_HOST', 'SMTP_PORT', 'SMTP_LOGIN', 'SMTP_PASSWORD', 'CHECK_FOR_NEW_VERSION', 'ENABLE_GZIP_OUTPUT', 'PLUGINS', 'CONFIG_VERSION'); ?>
diff --git a/include/sessions.php b/include/sessions.php
index 2cef1d91b..3355ec49e 100644
--- a/include/sessions.php
+++ b/include/sessions.php
@@ -53,7 +53,7 @@
$expire = time() + $session_expire;
- $data = db_escape_string(base64_encode($data), $session_connection);
+ $data = db_escape_string($session_connection, base64_encode($data), false);
if ($session_read) {
$query = "UPDATE ttrss_sessions SET data='$data',
@@ -71,7 +71,7 @@
global $session_connection;
- db_close($session_connection);
+ //db_close($session_connection);
return true;
}
@@ -96,7 +96,7 @@
db_query($session_connection, $query);
}
- if (!SINGLE_USER_MODE && DB_TYPE == "pgsql") {
+ if (!SINGLE_USER_MODE /* && DB_TYPE == "pgsql" */) {
session_set_save_handler("ttrss_open",
"ttrss_close", "ttrss_read", "ttrss_write",
"ttrss_destroy", "ttrss_gc");
diff --git a/include/version.php b/include/version.php
index 65af7f452..44d7cf53d 100644
--- a/include/version.php
+++ b/include/version.php
@@ -1,3 +1,3 @@
<?php
- define('VERSION', "1.7.4");
+ define('VERSION', "1.7.5");
?>