diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index a4445eb203..4c02214952 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -161,14 +161,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
failedAssetRestores++;
}
else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH))
- {
+ {
InventoryFolderBase foundFolder
= ReplicateArchivePathToUserInventory(
filePath, TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType,
rootDestinationFolder, foldersCreated, nodesLoaded);
if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType)
- {
+ {
+ // Escape back characters
+ filePath = filePath.Replace("/", "/");
+ filePath = filePath.Replace("&", "&");
+
InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data);
// Don't use the item ID that's in the file
@@ -289,6 +293,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR);
string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex);
+
+ // Escape back characters
+ newFolderName = newFolderName.Replace("/", "/");
+ newFolderName = newFolderName.Replace("&", "&");
+
UUID newFolderId = UUID.Random();
// Asset type has to be Unknown here rather than Folder, otherwise the created folder can't be
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 499c552a4a..af0b72f664 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -394,6 +394,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
///
public static string CreateArchiveFolderName(string name, UUID id)
{
+ // Only encode ampersands (for escaping anything) and / (since this is used as general dir separator).
+ name = name.Replace("&", "&");
+ name = name.Replace("/", "/");
+
return string.Format(
"{0}{1}{2}/",
name,
@@ -409,6 +413,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
///
public static string CreateArchiveItemName(string name, UUID id)
{
+ name = name.Replace("&", "&");
+ name = name.Replace("/", "/");
+
return string.Format(
"{0}{1}{2}.xml",
name,
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index 8ee9194533..41bb9dc5ef 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -135,7 +135,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
InventoryFolderBase objsFolder
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects");
item1.Folder = objsFolder.ID;
- scene.AddInventoryItem(userId, item1);
+ scene.AddInventoryItem(userId, item1);
MemoryStream archiveWriteStream = new MemoryStream();
archiverModule.OnInventoryArchiveSaved += SaveCompleted;
@@ -217,14 +217,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
string userItemCreatorLastName = "Lucan";
UUID userItemCreatorUuid = UUID.Parse("00000000-0000-0000-0000-000000000666");
- string itemName = "b.lsl";
- string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(itemName, UUID.Random());
+ string item1Name = "b.lsl";
+ string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1Name, UUID.Random());
MemoryStream archiveWriteStream = new MemoryStream();
TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
InventoryItemBase item1 = new InventoryItemBase();
- item1.Name = itemName;
+ item1.Name = item1Name;
item1.AssetID = UUID.Random();
item1.GroupID = UUID.Random();
item1.CreatorId = OspResolver.MakeOspa(userItemCreatorFirstName, userItemCreatorLastName);
@@ -258,7 +258,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
= scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName);
InventoryItemBase foundItem1
- = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, itemName);
+ = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, item1Name);
Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
Assert.That(
@@ -276,7 +276,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
archiverModule.DearchiveInventory(userFirstName, userLastName, "xA", "meowfood", archiveReadStream);
InventoryItemBase foundItem2
- = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xA/" + itemName);
+ = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xA/" + item1Name);
Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2");
// Now try loading to a more deeply nested folder
@@ -285,10 +285,102 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
archiverModule.DearchiveInventory(userFirstName, userLastName, "xB/xC", "meowfood", archiveReadStream);
InventoryItemBase foundItem3
- = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xB/xC/" + itemName);
+ = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xB/xC/" + item1Name);
Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3");
}
+ [Test]
+ public void TestIarV0_1WithEscapedChars()
+ {
+ TestHelper.InMethod();
+ log4net.Config.XmlConfigurator.Configure();
+
+ string itemName = "You & you are a mean man";
+ string userPassword = "meowfood";
+
+ InventoryArchiverModule archiverModule = new InventoryArchiverModule(true);
+
+ Scene scene = SceneSetupHelpers.SetupScene("Inventory");
+ SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
+ CommunicationsManager cm = scene.CommsManager;
+
+ // Create user
+ string userFirstName = "Jock";
+ string userLastName = "Stirrup";
+ UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
+
+ lock (this)
+ {
+ UserProfileTestUtils.CreateUserWithInventory(
+ cm, userFirstName, userLastName, userPassword, userId, InventoryReceived);
+ Monitor.Wait(this, 60000);
+ }
+
+ // Create asset
+ SceneObjectGroup object1;
+ SceneObjectPart part1;
+ {
+ string partName = "part name";
+ UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
+ PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
+ Vector3 groupPosition = new Vector3(10, 20, 30);
+ Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
+ Vector3 offsetPosition = new Vector3(5, 10, 15);
+
+ part1
+ = new SceneObjectPart(
+ ownerId, shape, groupPosition, rotationOffset, offsetPosition);
+ part1.Name = partName;
+
+ object1 = new SceneObjectGroup(part1);
+ scene.AddNewSceneObject(object1, false);
+ }
+
+ UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
+ AssetBase asset1 = new AssetBase();
+ asset1.FullID = asset1Id;
+ asset1.Data = Encoding.ASCII.GetBytes(SceneObjectSerializer.ToXml2Format(object1));
+ scene.AssetService.Store(asset1);
+
+ // Create item
+ UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
+ InventoryItemBase item1 = new InventoryItemBase();
+ item1.Name = itemName;
+ item1.AssetID = asset1.FullID;
+ item1.ID = item1Id;
+ InventoryFolderBase objsFolder
+ = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects");
+ item1.Folder = objsFolder.ID;
+ scene.AddInventoryItem(userId, item1);
+
+ MemoryStream archiveWriteStream = new MemoryStream();
+ archiverModule.OnInventoryArchiveSaved += SaveCompleted;
+
+ mre.Reset();
+ archiverModule.ArchiveInventory(
+ Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
+ mre.WaitOne(60000, false);
+
+ /// LOAD ITEM
+ MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
+
+ archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream);
+
+ CachedUserInfo userInfo
+ = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName);
+
+ InventoryItemBase foundItem1
+ = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userId, "Scripts/Objects/" + itemName);
+
+ Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
+// Assert.That(
+// foundItem1.CreatorId, Is.EqualTo(userUuid),
+// "Loaded item non-uuid creator doesn't match that of the loading user");
+ Assert.That(
+ foundItem1.Name, Is.EqualTo(itemName),
+ "Loaded item name doesn't match saved name");
+ }
+
///
/// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
/// embedded creators do not exist in the system
@@ -301,7 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
TestHelper.InMethod();
- log4net.Config.XmlConfigurator.Configure();
+ //log4net.Config.XmlConfigurator.Configure();
string userFirstName = "Charlie";
string userLastName = "Chan";
@@ -369,7 +461,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
{
TestHelper.InMethod();
- log4net.Config.XmlConfigurator.Configure();
+ //log4net.Config.XmlConfigurator.Configure();
string userFirstName = "Dennis";
string userLastName = "Menace";
diff --git a/OpenSim/Tests/Common/Setup/UserProfileTestUtils.cs b/OpenSim/Tests/Common/Setup/UserProfileTestUtils.cs
index 3ca44a12d1..1b06a46747 100644
--- a/OpenSim/Tests/Common/Setup/UserProfileTestUtils.cs
+++ b/OpenSim/Tests/Common/Setup/UserProfileTestUtils.cs
@@ -84,15 +84,35 @@ namespace OpenSim.Tests.Common.Setup
public static CachedUserInfo CreateUserWithInventory(
CommunicationsManager commsManager, string firstName, string lastName,
UUID userId, OnInventoryReceivedDelegate callback)
+ {
+ return CreateUserWithInventory(commsManager, firstName, lastName, "troll", userId, callback);
+ }
+
+ ///
+ /// Create a test user with a standard inventory
+ ///
+ ///
+ /// First name of user
+ /// Last name of user
+ /// Password
+ /// User ID
+ ///
+ /// Callback to invoke when inventory has been loaded. This is required because
+ /// loading may be asynchronous, even on standalone
+ ///
+ ///
+ public static CachedUserInfo CreateUserWithInventory(
+ CommunicationsManager commsManager, string firstName, string lastName, string password,
+ UUID userId, OnInventoryReceivedDelegate callback)
{
LocalUserServices lus = (LocalUserServices)commsManager.UserService;
- lus.AddUser(firstName, lastName, "troll", "bill@bailey.com", 1000, 1000, userId);
+ lus.AddUser(firstName, lastName, password, "bill@bailey.com", 1000, 1000, userId);
CachedUserInfo userInfo = commsManager.UserProfileCacheService.GetUserDetails(userId);
userInfo.OnInventoryReceived += callback;
userInfo.FetchInventory();
return userInfo;
- }
+ }
}
}
diff --git a/OpenSim/Tests/Common/TestHelper.cs b/OpenSim/Tests/Common/TestHelper.cs
index 4abf2e3688..9d530635f3 100644
--- a/OpenSim/Tests/Common/TestHelper.cs
+++ b/OpenSim/Tests/Common/TestHelper.cs
@@ -54,6 +54,7 @@ namespace OpenSim.Tests.Common
public static void InMethod()
{
StackTrace stackTrace = new StackTrace();
+ Console.WriteLine();
Console.WriteLine("===> In Test Method : {0} <===", stackTrace.GetFrame(1).GetMethod().Name);
}
}