beagle can't index filenames containing " Round 4 of my war against URI escaping... For a file named a"b, beagle hits this exception (which isn't too useful): ERROR: Caught exception inside Inotify.Event ERROR: System.Xml.XPath.XPathException: invalid operator name: 'b' in [0x001ba] (at /var/tmp/portage/mono-1.1.4/work/mono-1.1.4/mcs/class/System.XML/System.Xml.XPath/Tokenizer.cs:251) System.Xml.XPath.Tokenizer:ParseIdentifier () in [0x0031d] (at /var/tmp/portage/mono-1.1.4/work/mono-1.1.4/mcs/class/System.XML/System.Xml.XPath/Tokenizer.cs:414) System.Xml.XPath.Tokenizer:ParseToken () in [0x00010] (at /var/tmp/portage/mono-1.1.4/work/mono-1.1.4/mcs/class/System.XML/System.Xml.XPath/Tokenizer.cs:436) System.Xml.XPath.Tokenizer:advance () in [0x000cf] (at /var/tmp/portage/mono-1.1.4/work/mono-1.1.4/mcs/class/System.XML/System.Xml.XPath/Parser.cs:301) Mono.Xml.XPath.XPathParser:yyparse (Mono.Xml.XPath.yyParser.yyInput) in [0x00009] (at /var/tmp/portage/mono-1.1.4/work/mono-1.1.4/mcs/class/System.XML/System.Xml.XPath/Parser.jay:30) Mono.Xml.XPath.XPathParser:Compile (string) I tracked it down to the Nautilus stuff. The problem is that we are using an xpath query of : /directory/file[@name="a"b"] I looked at the format nautilus uses for filenames containing " and it escapes them to %22 It is also escaping other characters such as @ to their %-equivalent, so we should be escaping them too. So I split off the hex escaping into its own (non-URI-specific) method which we use in this context. Index: Util/NautilusTools.cs =================================================================== RCS file: /cvs/gnome/beagle/Util/NautilusTools.cs,v retrieving revision 1.4 diff -u -B -p -r1.4 NautilusTools.cs --- Util/NautilusTools.cs 17 Nov 2004 18:49:08 -0000 1.4 +++ Util/NautilusTools.cs 9 Mar 2005 23:47:22 -0000 @@ -96,8 +96,8 @@ namespace Beagle.Util { } else { doc = cached.doc; } - - string xpath = String.Format ("/directory/file[@name=\"{0}\"]", name); + + string xpath = String.Format ("/directory/file[@name=\"{0}\"]", StringFu.HexEscape (name)); return doc.SelectSingleNode (xpath); } Index: Util/StringFu.cs =================================================================== RCS file: /cvs/gnome/beagle/Util/StringFu.cs,v retrieving revision 1.17 diff -u -B -p -r1.17 StringFu.cs --- Util/StringFu.cs 6 Mar 2005 22:24:21 -0000 1.17 +++ Util/StringFu.cs 9 Mar 2005 23:47:22 -0000 @@ -271,23 +271,28 @@ namespace Beagle.Util { return false; } - static char[] CharsToQuote = { ';', '?', ':', '@', '&', '=', '$', ',', '#', '%', ' ' }; - static public string PathToQuotedFileUri (string path) - { + static char[] CharsToQuote = { ';', '?', ':', '@', '&', '=', '$', ',', '#', '%', '"', ' ' }; - StringBuilder builder = new StringBuilder (Uri.UriSchemeFile + Uri.SchemeDelimiter); + static public string HexEscape (string str) + { + StringBuilder builder = new StringBuilder (); int i; - path = Path.GetFullPath (path); - while ((i = path.IndexOfAny (CharsToQuote)) != -1) { + + while ((i = str.IndexOfAny (CharsToQuote)) != -1) { if (i > 0) - builder.Append (path.Substring (0, i)); - builder.Append (Uri.HexEscape (path [i])); - path = path.Substring (i+1); + builder.Append (str.Substring (0, i)); + builder.Append (Uri.HexEscape (str [i])); + str = str.Substring (i+1); } - builder.Append (path); - + builder.Append (str); + return builder.ToString (); + } + static public string PathToQuotedFileUri (string path) + { + path = Path.GetFullPath (path); + return Uri.UriSchemeFile + Uri.SchemeDelimiter + HexEscape (path); } // These strings should never be exposed to the user.