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:
Vadim Zeitlin
2021-03-22 16:14:31 +01:00
parent 71eff92873
commit 9e96ff972b
2 changed files with 48 additions and 5 deletions

View File

@@ -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;
}

View File

@@ -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