summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2012-02-21 12:36:29 +0400
committerAndrew Dolgov <[email protected]>2012-02-21 12:36:29 +0400
commit56fbb82cb004fb6f8689ee7f50be05d6a927f9f1 (patch)
tree6a0c3a21ece080f36cde838ef2910f291fa7765d
parent7b8ff151ed3d36214156906805e7e6327f59793c (diff)
properly handle invalid regular expressions supplied when testing filters, add some additional regexp checks (closes #427)
-rw-r--r--classes/pref_filters.php78
-rw-r--r--include/functions.php105
-rw-r--r--js/functions.js42
-rw-r--r--tt-rss.css4
4 files changed, 135 insertions, 94 deletions
diff --git a/classes/pref_filters.php b/classes/pref_filters.php
index c66e9e810..9b8c295ff 100644
--- a/classes/pref_filters.php
+++ b/classes/pref_filters.php
@@ -33,55 +33,65 @@ class Pref_Filters extends Protected_Handler {
else
$feed = -4;
- $feed_title = getFeedTitle($this->link, $feed);
-
- $qfh_ret = queryFeedHeadlines($this->link, $cat_filter ? $cat_id : $feed,
- 30, "", $cat_filter, false, false,
- false, "date_entered DESC", 0, $_SESSION["uid"], $filter);
-
- $result = $qfh_ret[0];
-
- $articles = array();
- $found = 0;
+ $regexp_valid = preg_match('/' . $filter['reg_exp'] . '/',
+ $filter['reg_exp']) !== FALSE;
print __("Articles matching this filter:");
print "<div class=\"inactiveFeedHolder\">";
print "<table width=\"100%\" cellspacing=\"0\" id=\"prefErrorFeedList\">";
- while ($line = db_fetch_assoc($result)) {
+ if ($regexp_valid) {
- $entry_timestamp = strtotime($line["updated"]);
- $entry_tags = get_article_tags($this->link, $line["id"], $_SESSION["uid"]);
+ $feed_title = getFeedTitle($this->link, $feed);
- $content_preview = truncate_string(
- strip_tags($line["content_preview"]), 100, '...');
+ $qfh_ret = queryFeedHeadlines($this->link, $cat_filter ? $cat_id : $feed,
+ 30, "", $cat_filter, false, false,
+ false, "date_entered DESC", 0, $_SESSION["uid"], $filter);
- if ($line["feed_title"])
- $feed_title = $line["feed_title"];
+ $result = $qfh_ret[0];
- print "<tr>";
+ $articles = array();
+ $found = 0;
- print "<td width='5%' align='center'><input
- dojoType=\"dijit.form.CheckBox\" checked=\"1\"
- disabled=\"1\" type=\"checkbox\"></td>";
- print "<td>";
+ while ($line = db_fetch_assoc($result)) {
- print $line["title"];
- print "&nbsp;(";
- print "<b>" . $feed_title . "</b>";
- print "):&nbsp;";
- print "<span class=\"insensitive\">" . $content_preview . "</span>";
- print " " . mb_substr($line["date_entered"], 0, 16);
+ $entry_timestamp = strtotime($line["updated"]);
+ $entry_tags = get_article_tags($this->link, $line["id"], $_SESSION["uid"]);
- print "</td></tr>";
+ $content_preview = truncate_string(
+ strip_tags($line["content_preview"]), 100, '...');
- $found++;
- }
+ if ($line["feed_title"])
+ $feed_title = $line["feed_title"];
+
+ print "<tr>";
+
+ print "<td width='5%' align='center'><input
+ dojoType=\"dijit.form.CheckBox\" checked=\"1\"
+ disabled=\"1\" type=\"checkbox\"></td>";
+ print "<td>";
+
+ print $line["title"];
+ print "&nbsp;(";
+ print "<b>" . $feed_title . "</b>";
+ print "):&nbsp;";
+ print "<span class=\"insensitive\">" . $content_preview . "</span>";
+ print " " . mb_substr($line["date_entered"], 0, 16);
+
+ print "</td></tr>";
+
+ $found++;
+ }
+
+ if ($found == 0) {
+ print "<tr><td align='center'>" .
+ __("No articles matching this filter has been found.") . "</td></tr>";
+ }
+ } else {
+ print "<tr><td align='center' class='error'>" .
+ __("Invalid regular expression.") . "</td></tr>";
- if ($found == 0) {
- print "<tr><td align='center'>" .
- __("No articles matching this filter has been found.") . "</td></tr>";
}
print "</table>";
diff --git a/include/functions.php b/include/functions.php
index 25c188ee6..dc5cbc816 100644
--- a/include/functions.php
+++ b/include/functions.php
@@ -4973,63 +4973,70 @@
function filter_to_sql($filter) {
$query = "";
- if (DB_TYPE == "pgsql")
- $reg_qpart = "~";
- else
- $reg_qpart = "REGEXP";
+ $regexp_valid = preg_match('/' . $filter['reg_exp'] . '/',
+ $filter['reg_exp']) !== FALSE;
- switch ($filter["type"]) {
- case "title":
- $query = "LOWER(ttrss_entries.title) $reg_qpart LOWER('".
- $filter['reg_exp'] . "')";
- break;
- case "content":
- $query = "LOWER(ttrss_entries.content) $reg_qpart LOWER('".
- $filter['reg_exp'] . "')";
- break;
- case "both":
- $query = "LOWER(ttrss_entries.title) $reg_qpart LOWER('".
- $filter['reg_exp'] . "') OR LOWER(" .
- "ttrss_entries.content) $reg_qpart LOWER('" . $filter['reg_exp'] . "')";
- break;
- case "tag":
- $query = "LOWER(ttrss_user_entries.tag_cache) $reg_qpart LOWER('".
- $filter['reg_exp'] . "')";
- break;
- case "link":
- $query = "LOWER(ttrss_entries.link) $reg_qpart LOWER('".
- $filter['reg_exp'] . "')";
- break;
- case "date":
+ if ($regexp_valid) {
- if ($filter["filter_param"] == "before")
- $cmp_qpart = "<";
- else
- $cmp_qpart = ">=";
+ if (DB_TYPE == "pgsql")
+ $reg_qpart = "~";
+ else
+ $reg_qpart = "REGEXP";
- $timestamp = date("Y-m-d H:N:s", strtotime($filter["reg_exp"]));
- $query = "ttrss_entries.date_entered $cmp_qpart '$timestamp'";
- break;
- case "author":
- $query = "LOWER(ttrss_entries.author) $reg_qpart LOWER('".
- $filter['reg_exp'] . "')";
- break;
- }
+ switch ($filter["type"]) {
+ case "title":
+ $query = "LOWER(ttrss_entries.title) $reg_qpart LOWER('".
+ $filter['reg_exp'] . "')";
+ break;
+ case "content":
+ $query = "LOWER(ttrss_entries.content) $reg_qpart LOWER('".
+ $filter['reg_exp'] . "')";
+ break;
+ case "both":
+ $query = "LOWER(ttrss_entries.title) $reg_qpart LOWER('".
+ $filter['reg_exp'] . "') OR LOWER(" .
+ "ttrss_entries.content) $reg_qpart LOWER('" . $filter['reg_exp'] . "')";
+ break;
+ case "tag":
+ $query = "LOWER(ttrss_user_entries.tag_cache) $reg_qpart LOWER('".
+ $filter['reg_exp'] . "')";
+ break;
+ case "link":
+ $query = "LOWER(ttrss_entries.link) $reg_qpart LOWER('".
+ $filter['reg_exp'] . "')";
+ break;
+ case "date":
- if ($filter["inverse"])
- $query = "NOT ($query)";
+ if ($filter["filter_param"] == "before")
+ $cmp_qpart = "<";
+ else
+ $cmp_qpart = ">=";
- if ($query) {
- if (DB_TYPE == "pgsql") {
- $query = " ($query) AND ttrss_entries.date_entered > NOW() - INTERVAL '14 days'";
- } else {
- $query = " ($query) AND ttrss_entries.date_entered > DATE_SUB(NOW(), INTERVAL 14 DAY)";
+ $timestamp = date("Y-m-d H:N:s", strtotime($filter["reg_exp"]));
+ $query = "ttrss_entries.date_entered $cmp_qpart '$timestamp'";
+ break;
+ case "author":
+ $query = "LOWER(ttrss_entries.author) $reg_qpart LOWER('".
+ $filter['reg_exp'] . "')";
+ break;
}
- $query .= " AND ";
- }
+ if ($filter["inverse"])
+ $query = "NOT ($query)";
- return $query;
+ if ($query) {
+ if (DB_TYPE == "pgsql") {
+ $query = " ($query) AND ttrss_entries.date_entered > NOW() - INTERVAL '14 days'";
+ } else {
+ $query = " ($query) AND ttrss_entries.date_entered > DATE_SUB(NOW(), INTERVAL 14 DAY)";
+ }
+ $query .= " AND ";
+ }
+
+ return $query;
+ } else {
+ return false;
+ }
}
// Status codes:
diff --git a/js/functions.js b/js/functions.js
index bd0d5fb73..4a4602f9e 100644
--- a/js/functions.js
+++ b/js/functions.js
@@ -982,19 +982,39 @@ function quickAddFilter() {
test: function() {
if (this.validate()) {
- if (dijit.byId("filterTestDlg"))
- dijit.byId("filterTestDlg").destroyRecursive();
+ var query = "?op=rpc&method=verifyRegexp&reg_exp=" +
+ param_escape(dialog.attr('value').reg_exp);
+
+ notify_progress("Verifying regular expression...");
+
+ new Ajax.Request("backend.php", {
+ parameters: query,
+ onComplete: function(transport) {
+ var reply = JSON.parse(transport.responseText);
+
+ if (reply) {
+ notify('');
+
+ if (!reply['status']) {
+ alert("Invalid regular expression.");
+ return;
+ } else {
- tdialog = new dijit.Dialog({
- id: "filterTestDlg",
- title: __("Filter Test Results"),
- style: "width: 600px",
- href: "backend.php?savemode=test&" +
- dojo.objectToQuery(dialog.attr('value')),
- });
+ if (dijit.byId("filterTestDlg"))
+ dijit.byId("filterTestDlg").destroyRecursive();
- tdialog.show();
+ tdialog = new dijit.Dialog({
+ id: "filterTestDlg",
+ title: __("Filter Test Results"),
+ style: "width: 600px",
+ href: "backend.php?savemode=test&" +
+ dojo.objectToQuery(dialog.attr('value')),
+ });
+ tdialog.show();
+ }
+ }
+ }});
}
},
execute: function() {
@@ -1014,7 +1034,7 @@ function quickAddFilter() {
notify('');
if (!reply['status']) {
- alert("Match regular expression seems to be invalid.");
+ alert("Invalid regular expression.");
return;
} else {
notify_progress("Saving data...", true);
diff --git a/tt-rss.css b/tt-rss.css
index 94aa75874..7a0ef8bbb 100644
--- a/tt-rss.css
+++ b/tt-rss.css
@@ -1407,3 +1407,7 @@ a.bookmarklet {
padding : 1em;
color : gray;
}
+
+td.error {
+ color : red;
+}