ResourceManager::findPath(): validate; accept absolute, read-allowed paths
- Perform the SGPath::validate() test for read access before returning a path obtained with a non-null second argument ("aContext"). - If SGPath(aContext, aResource) is an absolute path for which read access is authorized by SGPath::validate(), return it. This restores the possibility of using the 'play-audio-sample' FGCommand with an absolute, read-allowed path (was lost in FG commit 8853fded2953959). - Because a fair number of the existing uses of ResourceManager::findPath() are not quite correct IMO, we execute the final part where all providers are tried in turn even if SGPath(aContext, aResource) is an absolute path (otherwise, the sim wouldn't start because it couldn't load materials.xml---see [1]). - The SG_LOG call will spot a few errors in calling code/data, such as access tried for '/Aircraft/Generic/flightrecorder/generic-piston-propeller-4.xml' and '/Textures/Sky/cl_cumulus2.png'; since the function does not return at this point, these incorrect absolute paths which should be relative will still be given a chance with the BasePathProvider that has its base path set to $FG_ROOT; thus, they will be found as before this commit despite the new "access refused" warning (but please fix them!). This commit requires FlightGear commit e7594f46876fc6b0b. [1] https://sourceforge.net/p/flightgear/mailman/message/37697516/
This commit is contained in:
parent
7174cef8f4
commit
bb23af5d38
@ -314,7 +314,7 @@ void test_addAlreadyExistingResource()
|
|||||||
"add an already existing resource" << endl;
|
"add an already existing resource" << endl;
|
||||||
const auto& resMgr = EmbeddedResourceManager::instance();
|
const auto& resMgr = EmbeddedResourceManager::instance();
|
||||||
|
|
||||||
for (const string& locale: {"", "fr", "fr_FR"}) {
|
for (const string locale: {"", "fr", "fr_FR"}) {
|
||||||
// For these tests, we don't care about the resource contents -> no need
|
// For these tests, we don't care about the resource contents -> no need
|
||||||
// to substract 1 from the result of sizeof() as we did above.
|
// to substract 1 from the result of sizeof() as we did above.
|
||||||
unique_ptr<const RawEmbeddedResource> someRes(
|
unique_ptr<const RawEmbeddedResource> someRes(
|
||||||
@ -390,7 +390,7 @@ void test_getLocaleAndSelectLocale()
|
|||||||
"EmbeddedResourceManager" << endl;
|
"EmbeddedResourceManager" << endl;
|
||||||
const auto& resMgr = EmbeddedResourceManager::instance();
|
const auto& resMgr = EmbeddedResourceManager::instance();
|
||||||
|
|
||||||
for (const string& locale: {"", "fr", "fr_FR", "de_DE"}) {
|
for (const string locale: {"", "fr", "fr_FR", "de_DE"}) {
|
||||||
// The important effects of setLocale() are tested in
|
// The important effects of setLocale() are tested in
|
||||||
// test_localeDependencyOfResourceFetching()
|
// test_localeDependencyOfResourceFetching()
|
||||||
resMgr->selectLocale(locale);
|
resMgr->selectLocale(locale);
|
||||||
|
@ -127,15 +127,27 @@ void ResourceManager::removeProvider(ResourceProvider* aProvider)
|
|||||||
|
|
||||||
SGPath ResourceManager::findPath(const std::string& aResource, SGPath aContext)
|
SGPath ResourceManager::findPath(const std::string& aResource, SGPath aContext)
|
||||||
{
|
{
|
||||||
if (!aContext.isNull()) {
|
const SGPath completePath(aContext, aResource);
|
||||||
SGPath r(aContext, aResource);
|
|
||||||
if (r.exists()) {
|
if (!aContext.isNull() && completePath.exists()) {
|
||||||
return r;
|
return completePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Absolute, existing path and SGPath::validate() grants read access -> OK
|
||||||
|
if (completePath.isAbsolute()) {
|
||||||
|
const auto authorizedPath = completePath.validate(false);
|
||||||
|
if (!authorizedPath.isNull() && authorizedPath.exists()) {
|
||||||
|
return authorizedPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto provider : _providers) {
|
// Loop over the resource providers even if 'completePath' is absolute.
|
||||||
SGPath path = provider->resolve(aResource, aContext);
|
// For instance, when readProperties() processes 'include' attributes, it
|
||||||
|
// is expected that 'aResource' be interpreted relatively to 'aContext'
|
||||||
|
// or, if this doesn't lead to an existing file, a data path like
|
||||||
|
// $FG_ROOT. In the latter case, BasePathProvider will do the job.
|
||||||
|
for (const auto& provider : _providers) {
|
||||||
|
const SGPath path = provider->resolve(aResource, aContext);
|
||||||
if (!path.isNull()) {
|
if (!path.isNull()) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user