Viewing Issue Advanced Details

ID 0003731 Category [DMDirc] Commands Severity minor
Reproducibility always Date Submitted 2010-02-03 18:24 Last Update 2010-03-06 22:55
Reporter Dataforce Assigned To MD87 View Status public
Priority normal Status resolved Resolution fixed
Platform Fixed in Version Target Version 0.6.4
Product Version Product Build
Summary 0003731: /ignore command should validate input before adding it to the ignore list
Description
/ignore command should validate input before adding it to the ignore list
Needs unit test no
Upstream Bug URL

Relationships

related to 0003829resolvedMD87 /ignore should default to simple expressions with flag for regexps 

Notes

A patchset (2) related to this change has been added to gerrit by Gregory Holmes

Tabs -> Spaces for IgnoreList (No changes made) Ignore PatternSyntaxException
in ProcessMessage (needs validation done on adding, see issue 3731)

Fixes issue 3730

Change-Id: I0acece1f2c6c7b2c242c15c5240553de3b024455

A patchset (3) related to this change has been added to gerrit by Gregory Holmes

Tabs -> Spaces for IgnoreList (No changes made) Ignore PatternSyntaxException
in ProcessMessage (needs validation done on adding, see issue 3731)

Fixes issue 3730

Change-Id: I0acece1f2c6c7b2c242c15c5240553de3b024455
authorGregory Holmes <greg@dmdirc.com>2010-02-27 20:45:25 (GMT)
commit5879a8cec2a40593fe8cc073245f89faab08bfc4 (patch) (side-by-side diff)
Tabs -> Spaces for IgnoreList (No changes made)
Ignore PatternSyntaxException in ProcessMessage (needs validation done on adding, see issue 3731) Fixes issue 3730 Change-Id: I0acece1f2c6c7b2c242c15c5240553de3b024455 Reviewed-on: http://gerrit.dmdirc.com/932 Automatic-Compile: DMDirc Local Commits <dmdirc@googlemail.com> Reviewed-by: Shane Mc Cormack <shane@dmdirc.com>
-rw-r--r--src/com/dmdirc/parser/common/IgnoreList.java301
-rw-r--r--src/com/dmdirc/parser/irc/ProcessMessage.java6
2 files changed, 159 insertions, 148 deletions
Click to Expand/Collapse
diff src/com/dmdirc/parser/common/IgnoreList.java
@@ -33,135 +33,136 @@ import java.util.regex.PatternSyntaxException;
*/
public class IgnoreList {
- /** Arraylist storing ignore patterns. */
- protected final List<String> ignoreInfo = new ArrayList<String>();
-
- /**
- * Creates a new instance of RegexStringList.
- */
- public IgnoreList() {
- // Do nothing
- }
-
- /**
- * Creates a new instance of RegexStringList, with the specified items.
- *
- * @param items Items to add to this RegexStringList
- */
- public IgnoreList(final List<String> items) {
- addAll(items);
- }
-
- /**
- * Add a new ignore pattern to the ignore list.
- *
- * @param pattern Regex syntax for the ignore (Pattern is matched case-insensitively as ^pattern$)
- */
- public void add(final String pattern) {
- for (String target : ignoreInfo) {
- if (pattern.equalsIgnoreCase(target)) {
- return;
- }
- }
-
- ignoreInfo.add(pattern);
- }
-
- /**
- * Adds a set of patterns to the list.
- *
- * @param patterns A list of patterns to be added
- */
- public void addAll(final List<String> patterns) {
- for (String pattern : patterns) {
- add(pattern);
- }
- }
-
- /**
- * Delete an ignore from the list.
- *
- * @param position Position in the list to remove
- */
- public void remove(final int position) {
- if (position < this.count()) {
- ignoreInfo.remove(position);
- }
- }
-
- /**
- * Clear the ignore list.
- */
- public void clear() {
- ignoreInfo.clear();
- }
-
- /**
- * Check if a string matches any of the ignores in the list.
- *
- * @param check String to check (Patterns are matched case-insensitively as ^pattern$)
- * @return integer showing the position of the first match in the ignore list (-1 if none)
- * @throws PatternSyntaxException if one of the items in the list is an invalid regex
- */
- public int matches(final String check) throws PatternSyntaxException {
- for (int i = 0; i < this.count(); ++i) {
- if (check.matches("(?i)"+this.get(i))) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Check if a string matches a specific ignore in the list.
- *
- * @param position Position to check
- * @param check String to check (Patterns are matched case-insensitively as ^pattern$)
- * @return boolean true/false
- * @throws PatternSyntaxException if the item is an invalid regex
- */
- public boolean matches(final int position, final String check) throws PatternSyntaxException {
- if (position < this.count()) {
- return check.matches("(?i)"+this.get(position));
- } else {
- return false;
- }
- }
-
- /**
- * Get the ignore pattern in a given position in the list.
- *
- * @param position Position to check
- * @return String showing the pattern. ("" if position isn't valid)
- */
- public String get(final int position) {
- if (position < this.count()) {
- return ignoreInfo.get(position);
- } else {
- return "";
- }
- }
-
- /**
- * Change the ignore pattern in a given position in the list.
- *
- * @param position Position to change
- * @param pattern New pattern
- */
- public void set(final int position, final String pattern) {
- if (position < this.count()) {
- ignoreInfo.set(position, pattern);
- }
- }
-
- /**
- * Get the amount of ignores in the list.
- *
- * @return int showing the number of ignores
- */
- public int count() {
- return ignoreInfo.size();
- }
+ /** Arraylist storing ignore patterns. */
+ protected final List<String> ignoreInfo = new ArrayList<String>();
+
+ /**
+ * Creates a new instance of RegexStringList.
+ */
+ public IgnoreList() {
+ // Do nothing
+ }
+
+ /**
+ * Creates a new instance of RegexStringList, with the specified items.
+ *
+ * @param items Items to add to this RegexStringList
+ */
+ public IgnoreList(final List<String> items) {
+ addAll(items);
+ }
+
+ /**
+ * Add a new ignore pattern to the ignore list.
+ *
+ * @param pattern Regex syntax for the ignore (Pattern is matched case-insensitively as ^pattern$)
+ */
+ public void add(final String pattern) {
+ for (String target : ignoreInfo) {
+ if (pattern.equalsIgnoreCase(target)) {
+ return;
+ }
+ }
+
+ ignoreInfo.add(pattern);
+ }
+
+ /**
+ * Adds a set of patterns to the list.
+ *
+ * @param patterns A list of patterns to be added
+ */
+ public void addAll(final List<String> patterns) {
+ for (String pattern : patterns) {
+ add(pattern);
+ }
+ }
+
+ /**
+ * Delete an ignore from the list.
+ *
+ * @param position Position in the list to remove
+ */
+ public void remove(final int position) {
+ if (position < this.count()) {
+ ignoreInfo.remove(position);
+ }
+ }
+
+ /**
+ * Clear the ignore list.
+ */
+ public void clear() {
+ ignoreInfo.clear();
+ }
+
+ /**
+ * Check if a string matches any of the ignores in the list.
+ *
+ * @param check String to check (Patterns are matched case-insensitively as ^pattern$)
+ * @return integer showing the position of the first match in the ignore list (-1 if none)
+ * @throws PatternSyntaxException if one of the items in the list is an invalid regex
+ */
+ public int matches(final String check) throws PatternSyntaxException {
+ for (int i = 0; i < this.count(); ++i) {
+ if (check.matches("(?i)" + this.get(i))) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Check if a string matches a specific ignore in the list.
+ *
+ * @param position Position to check
+ * @param check String to check (Patterns are matched case-insensitively as ^pattern$)
+ * @return boolean true/false
+ * @throws PatternSyntaxException if the item is an invalid regex
+ */
+ public boolean matches(final int position, final String check) throws
+ PatternSyntaxException {
+ if (position < this.count()) {
+ return check.matches("(?i)" + this.get(position));
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get the ignore pattern in a given position in the list.
+ *
+ * @param position Position to check
+ * @return String showing the pattern. ("" if position isn't valid)
+ */
+ public String get(final int position) {
+ if (position < this.count()) {
+ return ignoreInfo.get(position);
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * Change the ignore pattern in a given position in the list.
+ *
+ * @param position Position to change
+ * @param pattern New pattern
+ */
+ public void set(final int position, final String pattern) {
+ if (position < this.count()) {
+ ignoreInfo.set(position, pattern);
+ }
+ }
+
+ /**
+ * Get the amount of ignores in the list.
+ *
+ * @return int showing the number of ignores
+ */
+ public int count() {
+ return ignoreInfo.size();
+ }
/**
* Adds the specified simple pattern to this ignore list.
@@ -244,11 +245,12 @@ public class IgnoreList {
res.append(part);
escaped = false;
- } else if (part == '\\') {
+ } else if (part == '\\') {
escaped = true;
} else if (part == '.') {
inchar = true;
- } else if (part == '.' || part == '^' || part == '$' || part == '['
+ } else if (part == '.' || part == '^' || part == '$' || part
+ == '['
|| part == ']' || part == '\\' || part == '(' || part == ')'
|| part == '{' || part == '}' || part == '|' || part == '+'
|| part == '*' || part == '?') {
@@ -281,23 +283,32 @@ public class IgnoreList {
for (char part : regex.toCharArray()) {
switch (part) {
- case '.': case '^': case '$': case '[': case ']': case '\\':
- case '(': case ')': case '{': case '}': case '|': case '+':
- res.append('\\');
- res.append(part);
- break;
- case '?':
- res.append('.');
- break;
- case '*':
- res.append('.');
- default:
- res.append(part);
- break;
+ case '.':
+ case '^':
+ case '$':
+ case '[':
+ case ']':
+ case '\\':
+ case '(':
+ case ')':
+ case '{':
+ case '}':
+ case '|':
+ case '+':
+ res.append('\\');
+ res.append(part);
+ break;
+ case '?':
+ res.append('.');
+ break;
+ case '*':
+ res.append('.');
+ default:
+ res.append(part);
+ break;
}
}
return res.toString();
}
-
}
Click to Expand/Collapse
diff src/com/dmdirc/parser/irc/ProcessMessage.java
@@ -76,9 +76,9 @@ public class ProcessMessage extends IRCProcessor {
try {
if (myParser.getIgnoreList().matches(sMessage) > -1) { return; }
} catch (PatternSyntaxException pse) {
- final ParserError pe = new ParserError(ParserError.ERROR_WARNING, "Error with ignore list regex: "+pse, myParser.getLastLine());
- pe.setException(pse);
- callErrorInfo(pe);
+ final ParserError pe = new ParserError(ParserError.ERROR_WARNING + ParserError.ERROR_USER, "Error with ignore list regex: "+pse, myParser.getLastLine());
+ pe.setException(pse);
+ callErrorInfo(pe);
}
// Lines such as:

A patchset (1) related to this change has been added to gerrit by Chris Smith

Ignore command improvements

Now operations on simple expressions by default
Now validates regular expression inputs

Fixes issue 3731
Fixes issue 3829

Change-Id: I00ac922564b5bb9deaeb78a3bf56baa7f8e6ea2f
authorChris Smith <chris@dmdirc.com>2010-03-06 22:22:25 (GMT)
committer Gregory Holmes <greg@dmdirc.com>2010-03-06 22:54:45 (GMT)
commit0b3bb41c3e249bf01ec2fe39c1ee54fc9619fa75 (patch) (side-by-side diff)
Ignore command improvements
Now operations on simple expressions by default Now validates regular expression inputs Fixes issue 3731 Fixes issue 3829 Change-Id: I00ac922564b5bb9deaeb78a3bf56baa7f8e6ea2f Reviewed-on: http://gerrit.dmdirc.com/963 Automatic-Compile: DMDirc Local Commits <dmdirc@googlemail.com> Reviewed-by: Gregory Holmes <greg@dmdirc.com>
-rw-r--r--src/com/dmdirc/commandparser/commands/server/Ignore.java194
1 files changed, 106 insertions, 88 deletions
Click to Expand/Collapse
diff src/com/dmdirc/commandparser/commands/server/Ignore.java
@@ -27,12 +27,14 @@ import com.dmdirc.commandparser.CommandArguments;
import com.dmdirc.commandparser.CommandManager;
import com.dmdirc.commandparser.commands.IntelligentCommand;
import com.dmdirc.commandparser.commands.ServerCommand;
-import com.dmdirc.config.Identity;
+import com.dmdirc.parser.common.IgnoreList;
import com.dmdirc.ui.input.AdditionalTabTargets;
import com.dmdirc.ui.input.TabCompletionType;
import com.dmdirc.ui.interfaces.InputWindow;
import java.util.List;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
/**
* Allows the user to add/view/delete ignores.
@@ -59,90 +61,103 @@ public final class Ignore extends ServerCommand implements IntelligentCommand {
@Override
public void execute(final InputWindow origin, final Server server,
final boolean isSilent, final CommandArguments args) {
-
- final Identity identity = server.getNetworkIdentity();
-
- if (args.getArguments().length == 0
- || args.getArguments()[0].toLowerCase().equals("view")) {
-
- if (identity.hasOptionString("network", "ignorelist")) {
- final List<String> list = identity.getOptionList("network", "ignorelist");
-
- if (list.isEmpty()) {
- sendLine(origin, isSilent, FORMAT_ERROR,
- "No ignore list entries for this network.");
-
- } else {
- sendLine(origin, isSilent, FORMAT_OUTPUT, "Ignore list:");
-
- int i = 0;
- for (String line : list) {
- if (!line.isEmpty()) {
- i++;
- sendLine(origin, isSilent, FORMAT_OUTPUT, i + ". " + line);
- }
- }
- }
-
- } else {
- sendLine(origin, isSilent, FORMAT_ERROR, "No ignore list entries for this network.");
- }
-
- } else if (args.getArguments()[0].toLowerCase().equals("add")
- && args.getArguments().length > 1) {
-
- final String host = args.getArgumentsAsString(1);
- String list = host;
-
- if (identity.hasOptionString("network", "ignorelist")) {
- list = identity.getOption("network", "ignorelist");
- list = list + "\n" + host;
- }
-
- identity.setOption("network", "ignorelist", list);
-
- sendLine(origin, isSilent, FORMAT_OUTPUT, "Added " + host + " to the ignore list.");
-
- } else if (args.getArguments()[0].toLowerCase().equals("remove")
- && args.getArguments().length > 1) {
-
- final String host = server.getParser().getStringConverter()
- .toLowerCase(args.getArgumentsAsString(1));
-
- final StringBuffer newlist = new StringBuffer();
- boolean found = false;
-
- if (identity.hasOptionString("network", "ignorelist")) {
- final String list = identity.getOption("network", "ignorelist");
-
-
- for (String entry : list.split("\n")) {
- if (server.getParser().getStringConverter()
- .toLowerCase(entry).equals(host)) {
- found = true;
- } else {
- if (newlist.length() > 0) {
- newlist.append('\n');
- }
- newlist.append(entry);
- }
- }
- }
-
- if (found) {
- identity.setOption("network", "ignorelist", newlist.toString());
- sendLine(origin, isSilent, FORMAT_OUTPUT, "Removed " + host
- + " from the ignore list.");
- } else {
- sendLine(origin, isSilent, FORMAT_ERROR, "Host '" + host + "' not found.");
- }
-
+
+ if (args.getArguments().length == 0) {
+ executeView(origin, server, isSilent, args, false);
+ } else if ("--remove".equalsIgnoreCase(args.getArguments()[0])) {
+ executeRemove(origin, server, isSilent, args);
+ } else if ("--regex".equalsIgnoreCase(args.getArguments()[0])) {
+ executeRegex(origin, server, isSilent, args);
} else {
- showUsage(origin, isSilent, "ignore", "<add|remove|view> [host]");
+ executeAdd(origin, server, isSilent, args);
+ }
+ }
+
+ protected void executeView(final InputWindow origin, final Server server,
+ final boolean isSilent, final CommandArguments args, final boolean forceRegex) {
+ final IgnoreList ignoreList = server.getIgnoreList();
+
+ if (ignoreList.count() == 0) {
+ sendLine(origin, isSilent, FORMAT_ERROR, "No ignore list entries for this network.");
+ return;
+ }
+
+ final List<String> entries;
+ if (ignoreList.canConvert() && !forceRegex) {
+ entries = ignoreList.getSimpleList();
+ } else {
+ if (!forceRegex) {
+ sendLine(origin, isSilent, FORMAT_ERROR,
+ "Unable to convert ignore list to simple format");
+ }
+ entries = ignoreList.getRegexList();
+ }
+
+ int i = 0;
+ for (String line : entries) {
+ i++;
+ sendLine(origin, isSilent, FORMAT_OUTPUT, i + ". " + line);
}
-
- server.updateIgnoreList();
-
+ }
+
+ protected void executeAdd(final InputWindow origin, final Server server,
+ final boolean isSilent, final CommandArguments args) {
+ final IgnoreList ignoreList = server.getIgnoreList();
+ final String target = args.getArgumentsAsString();
+
+ ignoreList.addSimple(target);
+ server.saveIgnoreList();
+ sendLine(origin, isSilent, FORMAT_OUTPUT, "Added " + target + " to the ignore list.");
+ }
+
+ protected void executeRegex(final InputWindow origin, final Server server,
+ final boolean isSilent, final CommandArguments args) {
+ if (args.getArguments().length == 1) {
+ executeView(origin, server, isSilent, args, true);
+ return;
+ }
+
+ final IgnoreList ignoreList = server.getIgnoreList();
+ final String target = args.getArgumentsAsString(1);
+
+ try {
+ Pattern.compile(target);
+ } catch (PatternSyntaxException ex) {
+ sendLine(origin, isSilent, FORMAT_ERROR, "Unable to compile regex: "
+ + ex.getDescription());
+ return;
+ }
+
+ ignoreList.add(target);
+ server.saveIgnoreList();
+ sendLine(origin, isSilent, FORMAT_OUTPUT, "Added " + target + " to the ignore list.");
+ }
+
+ protected void executeRemove(final InputWindow origin, final Server server,
+ final boolean isSilent, final CommandArguments args) {
+ if (args.getArguments().length == 1) {
+ showUsage(origin, isSilent, "ignore", "--remove <host>");
+ return;
+ }
+
+ final IgnoreList ignoreList = server.getIgnoreList();
+ final String host = args.getArgumentsAsString(1);
+
+ if (ignoreList.canConvert() && ignoreList.getSimpleList().contains(host)) {
+ ignoreList.remove(ignoreList.getSimpleList().indexOf(host));
+ server.saveIgnoreList();
+ sendLine(origin, isSilent, FORMAT_OUTPUT, "Removed " + host + " from the ignore list.");
+ return;
+ }
+
+ if (ignoreList.getRegexList().contains(host)) {
+ ignoreList.remove(ignoreList.getRegexList().indexOf(host));
+ server.saveIgnoreList();
+ sendLine(origin, isSilent, FORMAT_OUTPUT, "Removed " + host + " from the ignore list.");
+ return;
+ }
+
+ sendLine(origin, isSilent, FORMAT_ERROR, "Ignore list doesn't contain '" + host + "'.");
}
/** {@inheritDoc} */
@@ -160,7 +175,7 @@ public final class Ignore extends ServerCommand implements IntelligentCommand {
/** {@inheritDoc} */
@Override
public String getHelp() {
- return "ignore <add|remove|view> [host] - manages the network's ignore list";
+ return "ignore [--remove|--regex] [host] - manages the network's ignore list";
}
/** {@inheritDoc} */
@@ -170,12 +185,15 @@ public final class Ignore extends ServerCommand implements IntelligentCommand {
targets.excludeAll();
if (arg == 0) {
- targets.add("add");
- targets.add("remove");
- targets.add("view");
- } else if (arg == 1) {
+ targets.add("--regex");
+ targets.add("--remove");
+ targets.include(TabCompletionType.CHANNEL_NICK);
+ targets.include(TabCompletionType.QUERY_NICK);
+ } else if (arg == 1 && previousArgs.get(0).equals("--regex")) {
targets.include(TabCompletionType.CHANNEL_NICK);
targets.include(TabCompletionType.QUERY_NICK);
+ } else if (arg == 1 && previousArgs.get(0).equals("--remove")) {
+ // TODO: If/when passed a server, include known ignore list entries
}
return targets;

Issue History

Date Modified Username Field Change
2010-02-03 18:24 Dataforce New Issue
2010-02-03 18:24 Dataforce Status new => assigned
2010-02-03 18:24 Dataforce Assigned To => MD87
2010-02-25 06:01 MD87 Needs unit test => no
2010-02-25 06:01 MD87 Category *Unsorted => Commands
2010-02-25 06:01 MD87 Target Version 0.6.3 => 0.6.4
2010-02-27 22:07 Version Control Checkin
2010-02-27 22:07 Version Control Note Added: 0010009
2010-02-27 23:41 Version Control Checkin
2010-02-27 23:41 Version Control Note Added: 0010016
2010-02-27 23:47 Greboid Checkin
2010-02-27 23:47 Greboid Note Added: 0010019
2010-02-28 20:38 MD87 Relationship added related to 0003829
2010-03-06 22:23 Version Control Checkin
2010-03-06 22:23 Version Control Note Added: 0010117
2010-03-06 22:23 Version Control Status assigned => fix pending
2010-03-06 22:55 MD87 Checkin
2010-03-06 22:55 MD87 Note Added: 0010123
2010-03-06 22:55 MD87 Status fix pending => resolved
2010-03-06 22:55 MD87 Resolution open => fixed