From 668850b974fba428a527c01249e8e76619461d23 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 9 Nov 2009 15:49:09 +0000 Subject: * for iars, allow item names/folders including "/" to be escaped using "\/" * also, "\" has to be escaped as "\\" * add item name unit test for escaped characters --- .../Inventory/Archiver/InventoryArchiveUtils.cs | 83 +++++++++++++++++++++- .../Archiver/Tests/InventoryArchiverTests.cs | 8 ++- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 1 - 3 files changed, 87 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs index a822d10..e297c37 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs @@ -27,6 +27,9 @@ using System; using System.Collections.Generic; +using System.Reflection; +using System.Text; +using log4net; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Services.Interfaces; @@ -38,6 +41,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// public static class InventoryArchiveUtils { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public static readonly string PATH_DELIMITER = "/"; /// @@ -181,10 +186,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver public static InventoryItemBase FindItemByPath( IInventoryService inventoryService, InventoryFolderBase startFolder, string path) { - string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); + string[] components = SplitEscapedPath(path); + components[0] = UnescapePath(components[0]); + + //string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); if (components.Length == 1) { +// m_log.DebugFormat("FOUND SINGLE COMPONENT [{0}]", components[0]); + List items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); foreach (InventoryItemBase item in items) { @@ -194,6 +204,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver } else { +// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]); + InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); foreach (InventoryFolderBase folder in contents.Folders) @@ -206,5 +218,74 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // We didn't find an item or intermediate folder with the given name return null; } + + /// + /// Split a human escaped path into two components if it contains an unescaped path delimiter, or one component + /// if no delimiter is present + /// + /// + /// + /// The split path. We leave the components in their originally unescaped state (though we remove the delimiter + /// which originally split them if applicable). + /// + public static string[] SplitEscapedPath(string path) + { +// m_log.DebugFormat("SPLITTING PATH {0}", path); + + bool singleEscapeChar = false; + + for (int i = 0; i < path.Length; i++) + { + if (path[i] == '\\' && !singleEscapeChar) + { + singleEscapeChar = true; + } + else + { + if (PATH_DELIMITER == path[i].ToString() && !singleEscapeChar) + return new string[2] { path.Remove(i), path.Substring(i + 1) }; + else + singleEscapeChar = false; + } + } + + // We didn't find a delimiter + return new string[1] { path }; + } + + /// + /// Unescapes a human escaped path. This means that "\\" goes to "\", and "\/" goes to "/" + /// + /// + /// + public static string UnescapePath(string path) + { +// m_log.DebugFormat("ESCAPING PATH {0}", path); + + StringBuilder sb = new StringBuilder(); + + bool singleEscapeChar = false; + for (int i = 0; i < path.Length; i++) + { + if (path[i] == '\\' && !singleEscapeChar) + singleEscapeChar = true; + else + singleEscapeChar = false; + + if (singleEscapeChar) + { + if (PATH_DELIMITER == path[i].ToString()) + sb.Append(PATH_DELIMITER); + } + else + { + sb.Append(path[i]); + } + } + +// m_log.DebugFormat("ESCAPED PATH TO {0}", sb); + + return sb.ToString(); + } } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index c366150..bcae5f5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -296,7 +296,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests TestHelper.InMethod(); log4net.Config.XmlConfigurator.Configure(); - string itemName = "You & you are a mean man"; + string itemName = "You & you are a mean/man/"; + string humanEscapedItemName = @"You & you are a mean\/man\/"; string userPassword = "meowfood"; InventoryArchiverModule archiverModule = new InventoryArchiverModule(true); @@ -362,7 +363,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream); mre.WaitOne(60000, false); - /// LOAD ITEM + // LOAD ITEM MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream); @@ -371,7 +372,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName); InventoryItemBase foundItem1 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userId, "Scripts/Objects/" + itemName); + = InventoryArchiveUtils.FindItemByPath( + scene.InventoryService, userId, "Scripts/Objects/" + humanEscapedItemName); Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); // Assert.That( diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 00743fc..c689aba 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -93,7 +93,6 @@ namespace OpenSim.Region.Framework.Scenes public void AddInventoryItem(UUID AgentID, InventoryItemBase item) { - if (InventoryService.AddItem(item)) { int userlevel = 0; -- cgit v1.1