Fix wxXmlResource::Load() with HTTP URLs
Make the code in this function work even with wxFileSystemHandlers that don't implement FindFirst() at all: we can, and should, still try loading the passed in path with them, rather than not doing anything at all. This makes Load() works with HTTP URLs again, as it apparently used to do a long time ago, but didn't do any more. Add a unit test, even if only a semi-manual one, to try to help with this not getting broken again (ideal would be to launch our own HTTP server inside the test, but this is a bit more complicated). Closes #19109.
This commit is contained in:
@@ -343,7 +343,8 @@ bool wxXmlResource::Load(const wxString& filemask_)
|
||||
{
|
||||
wxString filemask = ConvertFileNameToURL(filemask_);
|
||||
|
||||
bool allOK = true;
|
||||
bool allOK = true,
|
||||
anyOK = false;
|
||||
|
||||
#if wxUSE_FILESYSTEM
|
||||
wxFileSystem fsys;
|
||||
@@ -356,33 +357,47 @@ bool wxXmlResource::Load(const wxString& filemask_)
|
||||
wxString fnd = wxXmlFindFirst;
|
||||
if ( fnd.empty() )
|
||||
{
|
||||
wxLogError(_("Cannot load resources from '%s'."), filemask);
|
||||
return false;
|
||||
// Some file system handlers (e.g. wxInternetFSHandler) just don't
|
||||
// implement FindFirst() at all, try using the original path as is.
|
||||
fnd = filemask;
|
||||
}
|
||||
|
||||
while (!fnd.empty())
|
||||
{
|
||||
bool thisOK = true;
|
||||
|
||||
#if wxUSE_FILESYSTEM
|
||||
if ( IsArchive(fnd) )
|
||||
{
|
||||
if ( !Load(fnd + wxT("#zip:*.xrc")) )
|
||||
allOK = false;
|
||||
thisOK = false;
|
||||
}
|
||||
else // a single resource URL
|
||||
#endif // wxUSE_FILESYSTEM
|
||||
{
|
||||
wxXmlDocument * const doc = DoLoadFile(fnd);
|
||||
if ( !doc )
|
||||
allOK = false;
|
||||
thisOK = false;
|
||||
else
|
||||
Data().push_back(new wxXmlResourceDataRecord(fnd, doc));
|
||||
}
|
||||
|
||||
if ( thisOK )
|
||||
anyOK = true;
|
||||
else
|
||||
allOK = false;
|
||||
|
||||
fnd = wxXmlFindNext;
|
||||
}
|
||||
# undef wxXmlFindFirst
|
||||
# undef wxXmlFindNext
|
||||
|
||||
if ( !anyOK )
|
||||
{
|
||||
wxLogError(_("Cannot load resources from '%s'."), filemask);
|
||||
return false;
|
||||
}
|
||||
|
||||
return allOK;
|
||||
}
|
||||
|
||||
|
@@ -19,6 +19,7 @@
|
||||
|
||||
#if wxUSE_XRC
|
||||
|
||||
#include "wx/fs_inet.h"
|
||||
#include "wx/xml/xml.h"
|
||||
#include "wx/sstream.h"
|
||||
#include "wx/wfstream.h"
|
||||
@@ -204,4 +205,31 @@ TEST_CASE_METHOD(XrcTestCase, "XRC::IDRanges", "[xrc]")
|
||||
}
|
||||
}
|
||||
|
||||
// This test is disabled by default as it requires the environment variable
|
||||
// below to be defined to point to a HTTP URL with the file to load.
|
||||
//
|
||||
// Use something like "python3 -m http.server samples/xrc/rc" and set
|
||||
// WX_TEST_XRC_URL to http://localhost/menu.xrc to run this test.
|
||||
TEST_CASE_METHOD(XrcTestCase, "XRC::LoadURL", "[xrc][.]")
|
||||
{
|
||||
wxString url;
|
||||
REQUIRE( wxGetEnv("WX_TEST_XRC_URL", &url) );
|
||||
|
||||
// Ensure that loading from HTTP URLs is supported.
|
||||
struct InetHandler : wxInternetFSHandler
|
||||
{
|
||||
InetHandler()
|
||||
{
|
||||
wxFileSystem::AddHandler(this);
|
||||
}
|
||||
|
||||
~InetHandler()
|
||||
{
|
||||
wxFileSystem::RemoveHandler(this);
|
||||
}
|
||||
} inetHandler;
|
||||
|
||||
CHECK( wxXmlResource::Get()->Load(url) );
|
||||
}
|
||||
|
||||
#endif // wxUSE_XRC
|
||||
|
Reference in New Issue
Block a user