]> git.saurik.com Git - wxWidgets.git/commitdiff
Fixed wxFileSystem::FileNameToURL() regression with UNC paths.
authorVáclav Slavík <vslavik@fastmail.fm>
Wed, 7 Apr 2010 18:59:51 +0000 (18:59 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Wed, 7 Apr 2010 18:59:51 +0000 (18:59 +0000)
We cannot use wxURI to do the escaping, because wxFileSystem depends on
use of nonstandard escaping and prefixes (wxURI eats away
file:// prefix, while wxFileSystem uses it to signify UNC paths;
wxFileSystem needs to escape #,: as well).

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63901 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/common/filesys.cpp

index 29e794e5705a9e8a795ac82f18b1d28b56e1cdb8..65fe27f61e25b606917aa113bc874998f10b7b79 100644 (file)
@@ -656,6 +656,42 @@ wxFileName wxFileSystem::URLToFileName(const wxString& url)
     return wxFileName(path, wxPATH_NATIVE);
 }
 
+// Escapes non-ASCII and others characters in file: URL to be valid URLs
+static wxString EscapeFileNameCharsInURL(const char *in)
+{
+    wxString s;
+
+    for ( const unsigned char *p = (const unsigned char*)in; *p; ++p )
+    {
+        const unsigned char c = *p;
+
+        // notice that all colons *must* be encoded in the paths used by
+        // wxFileSystem even though this makes URLs produced by this method
+        // unusable with IE under Windows as it requires "file:///c:/foo.bar"
+        // and doesn't accept "file:///c%3a/foo.bar" -- but then we never made
+        // any guarantees about general suitability of the strings returned by
+        // this method, they must work with wxFileSystem only and not encoding
+        // the colon breaks handling of
+        // "http://wherever/whatever.zip#zip:filename.ext" URLs so we really
+        // can't do this without heavy changes to the parsing code here, in
+        // particular in GetRightLocation()
+
+        if ( c == '/' || c == '-' || c == '.' || c == '_' || c == '~' ||
+             (c >= '0' && c <= '9') ||
+             (c >= 'a' && c <= 'z') ||
+             (c >= 'A' && c <= 'Z') )
+        {
+            s << c;
+        }
+        else
+        {
+            s << wxString::Format("%%%02x", c);
+        }
+    }
+
+    return s;
+}
+
 // Returns the file URL for a native path
 wxString wxFileSystem::FileNameToURL(const wxFileName& filename)
 {
@@ -680,24 +716,10 @@ wxString wxFileSystem::FileNameToURL(const wxFileName& filename)
 #endif
 
     url.Replace(g_nativePathString, g_unixPathString);
-    url.Replace(wxT("%"), wxT("%25")); // '%'s must be replaced first!
-    url.Replace(wxT("#"), wxT("%23"));
-
-    // notice that all colons *must* be encoded in the paths used by
-    // wxFileSystem even though this makes URLs produced by this method
-    // unusable with IE under Windows as it requires "file:///c:/foo.bar" and
-    // doesn't accept "file:///c%3a/foo.bar" -- but then we never made any
-    // guarantees about general suitability of the strings returned by this
-    // method, they must work with wxFileSystem only and not encoding the colon
-    // breaks handling of "http://wherever/whatever.zip#zip:filename.ext" URLs
-    // so we really can't do this without heavy changes to the parsing code
-    // here, in particular in GetRightLocation()
-    url.Replace(wxT(":"), wxT("%3A"));
-    url = wxT("file:") + url;
 
     // Do wxURI- and common practice-compatible escaping: encode the string
     // into UTF-8, then escape anything non-ASCII:
-    return wxURI(url).BuildURI();
+    return wxT("file:") + EscapeFileNameCharsInURL(url.utf8_str());
 }