Browse Source

Added resource name sanitation to prevent creation of duplicate resources.

Lasse Öörni 14 years ago
parent
commit
9b89a1540d

+ 1 - 0
Docs/ScriptAPI.dox

@@ -1040,6 +1040,7 @@ Methods:<br>
 - bool Exists(const String&) const
 - bool Exists(const String&) const
 - File@ GetFile(const String&)
 - File@ GetFile(const String&)
 - String GetPreferredResourceDir(const String&)
 - String GetPreferredResourceDir(const String&)
+- String SanitateResourceName(const String&)
 - const String& GetResourceName(StringHash)
 - const String& GetResourceName(StringHash)
 - Resource@ GetResource(const String&, const String&)
 - Resource@ GetResource(const String&, const String&)
 - Resource@ GetResource(ShortStringHash, StringHash)
 - Resource@ GetResource(ShortStringHash, StringHash)

+ 1 - 0
Engine/Engine/ResourceAPI.cpp

@@ -110,6 +110,7 @@ static void RegisterResourceCache(asIScriptEngine* engine)
     engine->RegisterObjectMethod("ResourceCache", "bool Exists(const String&in) const", asMETHODPR(ResourceCache, Exists, (const String&) const, bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "bool Exists(const String&in) const", asMETHODPR(ResourceCache, Exists, (const String&) const, bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "File@ GetFile(const String&in)", asFUNCTION(ResourceCacheGetFile), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("ResourceCache", "File@ GetFile(const String&in)", asFUNCTION(ResourceCacheGetFile), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("ResourceCache", "String GetPreferredResourceDir(const String&in)", asMETHOD(ResourceCache, GetPreferredResourceDir), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "String GetPreferredResourceDir(const String&in)", asMETHOD(ResourceCache, GetPreferredResourceDir), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ResourceCache", "String SanitateResourceName(const String&in)", asMETHOD(ResourceCache, SanitateResourceName), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "const String& GetResourceName(StringHash)", asMETHOD(ResourceCache, GetResourceName), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "const String& GetResourceName(StringHash)", asMETHOD(ResourceCache, GetResourceName), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "Resource@+ GetResource(const String&in, const String&in)", asFUNCTION(ResourceCacheGetResource), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("ResourceCache", "Resource@+ GetResource(const String&in, const String&in)", asFUNCTION(ResourceCacheGetResource), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("ResourceCache", "Resource@+ GetResource(ShortStringHash, StringHash)", asMETHODPR(ResourceCache, GetResource, (ShortStringHash, StringHash), Resource*), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "Resource@+ GetResource(ShortStringHash, StringHash)", asMETHODPR(ResourceCache, GetResource, (ShortStringHash, StringHash), Resource*), asCALL_THISCALL);

+ 15 - 2
Engine/Resource/ResourceCache.cpp

@@ -313,8 +313,10 @@ void ResourceCache::SetMemoryBudget(ShortStringHash type, unsigned budget)
     resourceGroups_[type].memoryBudget_ = budget;
     resourceGroups_[type].memoryBudget_ = budget;
 }
 }
 
 
-SharedPtr<File> ResourceCache::GetFile(const String& name)
+SharedPtr<File> ResourceCache::GetFile(const String& nameIn)
 {
 {
+    String name = SanitateResourceName(nameIn);
+    
     // Check first the packages
     // Check first the packages
     for (unsigned i = 0; i < packages_.Size(); ++i)
     for (unsigned i = 0; i < packages_.Size(); ++i)
     {
     {
@@ -343,8 +345,10 @@ SharedPtr<File> ResourceCache::GetFile(const String& name)
     return SharedPtr<File>();
     return SharedPtr<File>();
 }
 }
 
 
-Resource* ResourceCache::GetResource(ShortStringHash type, const String& name)
+Resource* ResourceCache::GetResource(ShortStringHash type, const String& nameIn)
 {
 {
+    String name = SanitateResourceName(nameIn);
+    
     // Add the name to the hash map, so if this is an unknown resource, the error will not be unintelligible
     // Add the name to the hash map, so if this is an unknown resource, the error will not be unintelligible
     StoreNameHash(name);
     StoreNameHash(name);
     
     
@@ -507,6 +511,15 @@ String ResourceCache::GetPreferredResourceDir(const String& path)
     return fixedPath;
     return fixedPath;
 }
 }
 
 
+String ResourceCache::SanitateResourceName(const String& nameIn)
+{
+    // Sanitate unsupported constructs from the resource name
+    String name = GetInternalPath(nameIn);
+    name.Replace("../", "");
+    name.Replace("./", "");
+    return name;
+}
+
 void ResourceCache::StoreNameHash(const String& name)
 void ResourceCache::StoreNameHash(const String& name)
 {
 {
     if (name.Empty())
     if (name.Empty())

+ 2 - 0
Engine/Resource/ResourceCache.h

@@ -118,6 +118,8 @@ public:
     const String& GetResourceName(StringHash nameHash) const;
     const String& GetResourceName(StringHash nameHash) const;
     /// Return either the path itself or its parent, based on which of them has recognized resource subdirectories.
     /// Return either the path itself or its parent, based on which of them has recognized resource subdirectories.
     String GetPreferredResourceDir(const String& path);
     String GetPreferredResourceDir(const String& path);
+    /// Remove unsupported constructs from the resource name to prevent ambiguity.
+    String SanitateResourceName(const String& name);
     /// Store a hash-to-name mapping.
     /// Store a hash-to-name mapping.
     void StoreNameHash(const String& name);
     void StoreNameHash(const String& name);