Skip to content

Commit a22256b

Browse files
CopilotlramosveagavinbarronCopilot
authored
fix: ItemWithPath now throws instead of generating malformed URLs with nullish path values (#3072)
* Initial plan * Fix ItemWithPath to throw on null/empty/whitespace path Co-authored-by: lramosvea <77297467+lramosvea@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * refactor(extensions): extract NormalizePathOrThrow helper; assert ParamName in tests Agent-Logs-Url: https://github.com/microsoftgraph/msgraph-sdk-dotnet/sessions/4583cb48-e9bd-44bd-935f-bf05c5334117 Co-authored-by: gavinbarron <7122716+gavinbarron@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lramosvea <77297467+lramosvea@users.noreply.github.com> Co-authored-by: Gavin Barron <gavinbarron@microsoft.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: gavinbarron <7122716+gavinbarron@users.noreply.github.com>
1 parent 11bd3af commit a22256b

2 files changed

Lines changed: 49 additions & 16 deletions

File tree

src/Microsoft.Graph/Extensions/DriveItemRequestBuilderExtensions.cs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,7 @@ public static class DriveItemRequestBuilderExtensions
4444
/// </summary>
4545
public static CustomDriveItemItemRequestBuilder ItemWithPath(this Microsoft.Graph.Drives.Item.Root.RootRequestBuilder rootRequestBuilder, string path)
4646
{
47-
if (!string.IsNullOrEmpty(path))
48-
{
49-
if (!path.StartsWith("/"))
50-
{
51-
path = string.Format("/{0}", path);
52-
}
53-
}
54-
47+
path = NormalizePathOrThrow(path);
5548
var requestInformation = rootRequestBuilder.ToGetRequestInformation();
5649
// Encode the path in accordance with the one drive spec
5750
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/concepts/addressing-driveitems
@@ -67,14 +60,7 @@ public static CustomDriveItemItemRequestBuilder ItemWithPath(this Microsoft.Grap
6760
/// </summary>
6861
public static CustomDriveItemItemRequestBuilder ItemWithPath(this Microsoft.Graph.Drives.Item.Items.Item.DriveItemItemRequestBuilder rootRequestBuilder, string path)
6962
{
70-
if (!string.IsNullOrEmpty(path))
71-
{
72-
if (!path.StartsWith("/"))
73-
{
74-
path = string.Format("/{0}", path);
75-
}
76-
}
77-
63+
path = NormalizePathOrThrow(path);
7864
var requestInformation = rootRequestBuilder.ToGetRequestInformation();
7965
// Encode the path in accordance with the one drive spec
8066
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/concepts/addressing-driveitems
@@ -84,6 +70,17 @@ public static CustomDriveItemItemRequestBuilder ItemWithPath(this Microsoft.Grap
8470
return new CustomDriveItemItemRequestBuilder(rootRequestBuilder.GetPathParameters(), rootRequestBuilder.GetRequestAdapter(),rootRequestBuilder.GetUrlTemplate().Replace("{driveItem%2Did}",$"{{driveItem%2Did}}:{parameter}:"));
8571
}
8672

73+
private static string NormalizePathOrThrow(string path)
74+
{
75+
if (path is null)
76+
throw new ArgumentNullException(nameof(path));
77+
if (string.IsNullOrWhiteSpace(path))
78+
throw new ArgumentException("path cannot be empty or whitespace.", nameof(path));
79+
if (!path.StartsWith("/", StringComparison.Ordinal))
80+
path = string.Format("/{0}", path);
81+
return path;
82+
}
83+
8784
private static IRequestAdapter GetRequestAdapter(this object obj) {
8885
var field = obj.GetType()
8986
.BaseType!

tests/Microsoft.Graph.DotnetCore.Test/Requests/Extensions/DriveItemRequestBuilderExtensionsTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,5 +141,41 @@ public void ItemByPath_BuildRequestWithNestedPathSlashAndMoreThanOneParameter()
141141
Assert.NotNull(itemRequestInformation);
142142
Assert.Equal(expectedRequestUri, itemRequestInformation.URI);
143143
}
144+
[Fact]
145+
public void ItemByPath_ThrowsArgumentNullException_WhenPathIsNull_Root()
146+
{
147+
var graphServiceClient = new GraphServiceClient(new MockAuthenticationProvider().Object);
148+
var ex = Assert.Throws<ArgumentNullException>(() => graphServiceClient.Drives["driveId"].Root.ItemWithPath(null));
149+
Assert.Equal("path", ex.ParamName);
150+
}
151+
152+
[Theory]
153+
[InlineData("")]
154+
[InlineData(" ")]
155+
public void ItemByPath_ThrowsArgumentException_WhenPathIsEmptyOrWhitespace_Root(string path)
156+
{
157+
var graphServiceClient = new GraphServiceClient(new MockAuthenticationProvider().Object);
158+
var ex = Assert.Throws<ArgumentException>(() => graphServiceClient.Drives["driveId"].Root.ItemWithPath(path));
159+
Assert.Equal("path", ex.ParamName);
160+
}
161+
162+
[Fact]
163+
public void ItemByPath_ThrowsArgumentNullException_WhenPathIsNull_DriveItem()
164+
{
165+
var graphServiceClient = new GraphServiceClient(new MockAuthenticationProvider().Object);
166+
var ex = Assert.Throws<ArgumentNullException>(() => graphServiceClient.Drives["driveId"].Items["itemId"].ItemWithPath(null));
167+
Assert.Equal("path", ex.ParamName);
168+
}
169+
170+
[Theory]
171+
[InlineData("")]
172+
[InlineData(" ")]
173+
public void ItemByPath_ThrowsArgumentException_WhenPathIsEmptyOrWhitespace_DriveItem(string path)
174+
{
175+
var graphServiceClient = new GraphServiceClient(new MockAuthenticationProvider().Object);
176+
var ex = Assert.Throws<ArgumentException>(() => graphServiceClient.Drives["driveId"].Items["itemId"].ItemWithPath(path));
177+
Assert.Equal("path", ex.ParamName);
178+
}
179+
144180
}
145181
}

0 commit comments

Comments
 (0)