From 9e96ff972ba0e1617bb8b17210b70faae4a011d3 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 22 Mar 2021 16:14:31 +0100 Subject: [PATCH] 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. --- src/xrc/xmlres.cpp | 25 ++++++++++++++++++++----- tests/xml/xrctest.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index 4ffeda9723..e6248d4716 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -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; } diff --git a/tests/xml/xrctest.cpp b/tests/xml/xrctest.cpp index 4aff56711a..04e1a435ff 100644 --- a/tests/xml/xrctest.cpp +++ b/tests/xml/xrctest.cpp @@ -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