Fix path/URL confusion in wxLaunchDefaultBrowser()
Add a helper wxLaunchBrowserParams struct with clearly distinct "url" and "path" fields and GetPathOrURL() accessor which returns whichever is appropriate. This makes the code more clear and ensures that we never pass URLs (but only file paths) to xdg-open under Unix as it doesn't handle them. See #17227.
This commit is contained in:
@@ -69,8 +69,10 @@
|
||||
#include <errno.h>
|
||||
|
||||
#if wxUSE_GUI
|
||||
#include "wx/filesys.h"
|
||||
#include "wx/notebook.h"
|
||||
#include "wx/statusbr.h"
|
||||
#include "wx/private/launchbrowser.h"
|
||||
#endif // wxUSE_GUI
|
||||
|
||||
#include <time.h>
|
||||
@@ -84,7 +86,6 @@
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
#include "wx/msw/private.h"
|
||||
#include "wx/filesys.h"
|
||||
#endif
|
||||
|
||||
#if wxUSE_GUI && defined(__WXGTK__)
|
||||
@@ -1017,20 +1018,17 @@ bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) )
|
||||
// Launch default browser
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
#if defined(__WINDOWS__) || \
|
||||
defined(__WXX11__) || defined(__WXGTK__) || defined(__WXMOTIF__) || \
|
||||
defined(__WXOSX__)
|
||||
|
||||
// implemented in a port-specific utils source file:
|
||||
bool wxDoLaunchDefaultBrowser(const wxString& url, const wxString& scheme, int flags);
|
||||
|
||||
#elif defined(__WXX11__) || defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXOSX__)
|
||||
|
||||
// implemented in a port-specific utils source file:
|
||||
bool wxDoLaunchDefaultBrowser(const wxString& url, int flags);
|
||||
bool wxDoLaunchDefaultBrowser(const wxLaunchBrowserParams& params);
|
||||
|
||||
#else
|
||||
|
||||
// a "generic" implementation:
|
||||
bool wxDoLaunchDefaultBrowser(const wxString& url, int flags)
|
||||
bool wxDoLaunchDefaultBrowser(const wxLaunchBrowserParams& params)
|
||||
{
|
||||
// on other platforms try to use mime types or wxExecute...
|
||||
|
||||
@@ -1044,7 +1042,7 @@ bool wxDoLaunchDefaultBrowser(const wxString& url, int flags)
|
||||
wxString mt;
|
||||
ft->GetMimeType(&mt);
|
||||
|
||||
ok = ft->GetOpenCommand(&cmd, wxFileType::MessageParameters(url));
|
||||
ok = ft->GetOpenCommand(&cmd, wxFileType::MessageParameters(params.url));
|
||||
delete ft;
|
||||
}
|
||||
#endif // wxUSE_MIMETYPE
|
||||
@@ -1053,7 +1051,7 @@ bool wxDoLaunchDefaultBrowser(const wxString& url, int flags)
|
||||
{
|
||||
// fallback to checking for the BROWSER environment variable
|
||||
if ( !wxGetEnv(wxT("BROWSER"), &cmd) || cmd.empty() )
|
||||
cmd << wxT(' ') << url;
|
||||
cmd << wxT(' ') << params.url;
|
||||
}
|
||||
|
||||
ok = ( !cmd.empty() && wxExecute(cmd) );
|
||||
@@ -1067,90 +1065,54 @@ bool wxDoLaunchDefaultBrowser(const wxString& url, int flags)
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool DoLaunchDefaultBrowserHelper(const wxString& urlOrig, int flags)
|
||||
static bool DoLaunchDefaultBrowserHelper(const wxString& url, int flags)
|
||||
{
|
||||
// NOTE: we don't have to care about the wxBROWSER_NOBUSYCURSOR flag
|
||||
// as it was already handled by wxLaunchDefaultBrowser
|
||||
wxLaunchBrowserParams params(flags);
|
||||
|
||||
wxUnusedVar(flags);
|
||||
|
||||
wxString url(urlOrig), scheme;
|
||||
wxURI uri(url);
|
||||
const wxURI uri(url);
|
||||
|
||||
// this check is useful to avoid that wxURI recognizes as scheme parts of
|
||||
// the filename, in case urlOrig is a local filename
|
||||
// the filename, in case url is a local filename
|
||||
// (e.g. "C:\\test.txt" when parsed by wxURI reports a scheme == "C")
|
||||
bool hasValidScheme = uri.HasScheme() && uri.GetScheme().length() > 1;
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
|
||||
// NOTE: when testing wxMSW's wxLaunchDefaultBrowser all possible forms
|
||||
// of the URL/flags should be tested; e.g.:
|
||||
//
|
||||
// for (int i=0; i<2; i++)
|
||||
// {
|
||||
// // test arguments without a valid URL scheme:
|
||||
// wxLaunchDefaultBrowser("C:\\test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
|
||||
// wxLaunchDefaultBrowser("wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
|
||||
//
|
||||
// // test arguments with different valid schemes:
|
||||
// wxLaunchDefaultBrowser("file:/C%3A/test.txt", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
|
||||
// wxLaunchDefaultBrowser("http://wxwidgets.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
|
||||
// wxLaunchDefaultBrowser("mailto:user@host.org", i==0 ? 0 : wxBROWSER_NEW_WINDOW);
|
||||
// }
|
||||
// (assuming you have a C:\test.txt file)
|
||||
|
||||
if ( !hasValidScheme )
|
||||
{
|
||||
if (wxFileExists(urlOrig) || wxDirExists(urlOrig))
|
||||
if (wxFileExists(url) || wxDirExists(url))
|
||||
{
|
||||
scheme = "file";
|
||||
// do not prepend the file scheme to the URL as ShellExecuteEx() doesn't like it
|
||||
params.scheme = "file";
|
||||
params.path = url;
|
||||
}
|
||||
else
|
||||
{
|
||||
url.Prepend(wxS("http://"));
|
||||
scheme = "http";
|
||||
params.scheme = "http";
|
||||
}
|
||||
|
||||
params.url << params.scheme << wxS("://") << url;
|
||||
}
|
||||
else if ( hasValidScheme )
|
||||
{
|
||||
scheme = uri.GetScheme();
|
||||
params.url = url;
|
||||
params.scheme = uri.GetScheme();
|
||||
|
||||
if ( uri.GetScheme() == "file" )
|
||||
if ( params.scheme == "file" )
|
||||
{
|
||||
// TODO: extract URLToFileName() to some always compiled in
|
||||
// function
|
||||
#if wxUSE_FILESYSTEM
|
||||
// ShellExecuteEx() doesn't like the "file" scheme when opening local files;
|
||||
// remove it
|
||||
url = wxFileSystem::URLToFileName(url).GetFullPath();
|
||||
// for same reason as above, remove the scheme from the URL
|
||||
params.path = wxFileSystem::URLToFileName(url).GetFullPath();
|
||||
#endif // wxUSE_FILESYSTEM
|
||||
}
|
||||
}
|
||||
|
||||
if (wxDoLaunchDefaultBrowser(url, scheme, flags))
|
||||
return true;
|
||||
//else: call wxLogSysError
|
||||
#else
|
||||
if ( !hasValidScheme )
|
||||
if ( !wxDoLaunchDefaultBrowser(params) )
|
||||
{
|
||||
// set the scheme of url to "http" or "file" if it does not have one
|
||||
if (wxFileExists(urlOrig) || wxDirExists(urlOrig))
|
||||
url.Prepend(wxS("file://"));
|
||||
else
|
||||
url.Prepend(wxS("http://"));
|
||||
wxLogSysError(_("Failed to open URL \"%s\" in default browser."), url);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wxDoLaunchDefaultBrowser(url, flags))
|
||||
return true;
|
||||
//else: call wxLogSysError
|
||||
#endif
|
||||
|
||||
wxLogSysError(_("Failed to open URL \"%s\" in default browser."),
|
||||
url.c_str());
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxLaunchDefaultBrowser(const wxString& url, int flags)
|
||||
|
Reference in New Issue
Block a user