Skip to content
This repository was archived by the owner on Nov 15, 2018. It is now read-only.

Commit bf9fd0d

Browse files
Iamcerbapranavkm
authored andcommitted
Prevent null refs when copying a property with a null value
* Fix dotnet/aspnetcore#3559 Json Patch: System.NullReferenceException while trying to use copy operation from property with null value. * Fix dotnet/aspnetcore#3559: Missing tests added.
1 parent 891ae28 commit bf9fd0d

File tree

6 files changed

+66
-4
lines changed

6 files changed

+66
-4
lines changed

src/Microsoft.AspNetCore.JsonPatch/Adapters/ObjectAdapter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ public void Copy(Operation operation, object objectToApplyTo)
229229
if (TryGetValue(operation.from, objectToApplyTo, operation, out var propertyValue))
230230
{
231231
// Create deep copy
232-
var copyResult = ConversionResultProvider.CopyTo(propertyValue, propertyValue.GetType());
232+
var copyResult = ConversionResultProvider.CopyTo(propertyValue, propertyValue?.GetType());
233233
if (copyResult.CanBeConverted)
234234
{
235235
Add(operation.path,

src/Microsoft.AspNetCore.JsonPatch/Internal/ConversionResultProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public static ConversionResult CopyTo(object value, Type typeToConvertTo)
3939
var targetType = typeToConvertTo;
4040
if (value == null)
4141
{
42-
return new ConversionResult(IsNullableType(typeToConvertTo), null);
42+
return new ConversionResult(canBeConverted: true, convertedInstance: null);
4343
}
4444
else if (typeToConvertTo.IsAssignableFrom(value.GetType()))
4545
{

src/Microsoft.AspNetCore.JsonPatch/JsonPatchDocumentOfT.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ public JsonPatchDocument<TModel> Move<TProp>(
503503
}
504504

505505
/// <summary>
506-
/// Copy the value at specified location to the target location. Willr esult in, for example:
506+
/// Copy the value at specified location to the target location. Will result in, for example:
507507
/// { "op": "copy", "from": "/a/b/c", "path": "/a/b/e" }
508508
/// </summary>
509509
/// <param name="from">source location</param>

test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/ExpandoObjectIntegrationTest.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,25 @@ public void CopyStringProperty_ToAnotherStringProperty()
159159
Assert.Equal("A", targetObject.AnotherStringProperty);
160160
}
161161

162+
[Fact]
163+
public void CopyNullStringProperty_ToAnotherStringProperty()
164+
{
165+
// Arrange
166+
dynamic targetObject = new ExpandoObject();
167+
168+
targetObject.StringProperty = null;
169+
targetObject.AnotherStringProperty = "B";
170+
171+
var patchDocument = new JsonPatchDocument();
172+
patchDocument.Copy("StringProperty", "AnotherStringProperty");
173+
174+
// Act
175+
patchDocument.ApplyTo(targetObject);
176+
177+
// Assert
178+
Assert.Null(targetObject.AnotherStringProperty);
179+
}
180+
162181
[Fact]
163182
public void MoveIntegerValue_ToAnotherIntegerProperty()
164183
{

test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/NestedObjectIntegrationTest.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,30 @@ public void CopyStringProperty_ToAnotherStringProperty()
175175

176176
// Assert
177177
Assert.Equal("A", targetObject.SimpleObject.AnotherStringProperty);
178-
}
178+
}
179+
180+
[Fact]
181+
public void CopyNullStringProperty_ToAnotherStringProperty()
182+
{
183+
// Arrange
184+
var targetObject = new SimpleObjectWithNestedObject()
185+
{
186+
SimpleObject = new SimpleObject()
187+
{
188+
StringProperty = null,
189+
AnotherStringProperty = "B"
190+
}
191+
};
192+
193+
var patchDocument = new JsonPatchDocument<SimpleObjectWithNestedObject>();
194+
patchDocument.Copy(o => o.SimpleObject.StringProperty, o => o.SimpleObject.AnotherStringProperty);
195+
196+
// Act
197+
patchDocument.ApplyTo(targetObject);
198+
199+
// Assert
200+
Assert.Null(targetObject.SimpleObject.AnotherStringProperty);
201+
}
179202

180203
[Fact]
181204
public void Copy_DeepClonesObject()

test/Microsoft.AspNetCore.JsonPatch.Test/IntegrationTests/SimpleObjectIntegrationTest.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,26 @@ public void CopyStringProperty_ToAnotherStringProperty()
4646
Assert.Equal("A", targetObject.AnotherStringProperty);
4747
}
4848

49+
[Fact]
50+
public void CopyNullStringProperty_ToAnotherStringProperty()
51+
{
52+
// Arrange
53+
var targetObject = new SimpleObject()
54+
{
55+
StringProperty = null,
56+
AnotherStringProperty = "B"
57+
};
58+
59+
var patchDocument = new JsonPatchDocument();
60+
patchDocument.Copy("StringProperty", "AnotherStringProperty");
61+
62+
// Act
63+
patchDocument.ApplyTo(targetObject);
64+
65+
// Assert
66+
Assert.Null(targetObject.AnotherStringProperty);
67+
}
68+
4969
[Fact]
5070
public void MoveIntegerProperty_ToAnotherIntegerProperty()
5171
{

0 commit comments

Comments
 (0)