Skip to content

Commit 179caac

Browse files
Throw if attempting to use the default unique media path scheme with version 7 GUIDs (#19419)
* Thow if attempting to use the default unique media path scheme with version 7 GUIDs. * Expanded unittests, fixed null params, chose a better exception * Use parameters in test. --------- Co-authored-by: Migaroez <[email protected]>
1 parent 933fa54 commit 179caac

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

src/Umbraco.Core/IO/MediaPathSchemes/UniqueMediaPathScheme.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@ public class UniqueMediaPathScheme : IMediaPathScheme
1313
/// <inheritdoc />
1414
public string GetFilePath(MediaFileManager fileManager, Guid itemGuid, Guid propertyGuid, string filename)
1515
{
16+
// Shortening of the Guid to 8 chars risks collisions with GUIDs, which are expected to be very rare.
17+
// However with GUID 7, the chance is much higher, as those created in a short period of time could have
18+
// the same first 8 characters.
19+
// Such GUIDs would have been created via Guid.CreateVersion7() rather than Guid.NewGuid().
20+
// We should detect that, throw, and recommend creation of standard GUIDs or the use of a custom IMediaPathScheme instead.
21+
if (itemGuid.Version == 7 || propertyGuid.Version == 7)
22+
{
23+
throw new ArgumentException(
24+
"The UniqueMediaPathScheme cannot be used with version 7 GUIDs due to an increased risk of collisions in the generated file paths. " +
25+
"Please use version 4 GUIDs created via Guid.NewGuid() or implement and register a different IMediaPathScheme.");
26+
}
27+
1628
Guid combinedGuid = GuidUtils.Combine(itemGuid, propertyGuid);
1729
var directory = GuidUtils.ToBase32String(combinedGuid, DirectoryLength);
1830

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using Microsoft.Extensions.Logging;
2+
using Moq;
3+
using NUnit.Framework;
4+
using Umbraco.Cms.Core.IO;
5+
using Umbraco.Cms.Core.IO.MediaPathSchemes;
6+
using Umbraco.Cms.Core.Strings;
7+
8+
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.IO.MediaPathSchemes;
9+
10+
[TestFixture]
11+
public class UniqueMediaPathSchemeTests
12+
{
13+
private static MediaFileManager MediaFileManager => new(
14+
Mock.Of<IFileSystem>(),
15+
Mock.Of<IMediaPathScheme>(),
16+
Mock.Of<ILogger<MediaFileManager>>(),
17+
Mock.Of<IShortStringHelper>(),
18+
Mock.Of<IServiceProvider>());
19+
20+
[Test]
21+
public void GetFilePath_Creates_ExpectedPath()
22+
{
23+
var scheme = new UniqueMediaPathScheme();
24+
var itemGuid = new Guid("00000000-0000-4000-0000-000000000001");
25+
var propertyGuid = new Guid("00000000-0000-4000-0000-000000000002");
26+
var filename = "test.txt";
27+
string actualPath = scheme.GetFilePath(MediaFileManager, itemGuid, propertyGuid, filename);
28+
Assert.AreEqual("aaaaaaaa/test.txt", actualPath);
29+
}
30+
31+
[TestCase(true, false)]
32+
[TestCase(false, true)]
33+
[TestCase(true, true)]
34+
public void GetFilePath_ShouldThrow_WhenUsingVersion7Guids(bool userVersion7ForItemGuid, bool userVersion7ForPropertyGuid)
35+
{
36+
var scheme = new UniqueMediaPathScheme();
37+
var itemGuid = new Guid($"00000000-0000-{(userVersion7ForItemGuid ? "7" : "4")}000-0000-000000000001");
38+
var propertyGuid = new Guid($"00000000-0000-{(userVersion7ForPropertyGuid ? "7" : "4")}000-0000-000000000002");
39+
var filename = "test.txt";
40+
41+
Assert.Throws<ArgumentException>(() => scheme.GetFilePath(MediaFileManager, itemGuid, propertyGuid, filename));
42+
}
43+
}

0 commit comments

Comments
 (0)