Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix deserialization of null maps in reflection-free Jackson deserializers #44421

Merged
merged 1 commit into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -239,18 +239,18 @@ private boolean deserializeObject(ClassInfo classInfo, ResultHandle objHandle, C
ResultHandle nextField = loopCreator
.invokeInterfaceMethod(ofMethod(Iterator.class, "next", Object.class), fieldsIterator);
ResultHandle mapEntry = loopCreator.checkCast(nextField, Map.Entry.class);
ResultHandle fieldName = loopCreator
.invokeInterfaceMethod(ofMethod(Map.Entry.class, "getKey", Object.class), mapEntry);
ResultHandle fieldValue = loopCreator.checkCast(loopCreator
.invokeInterfaceMethod(ofMethod(Map.Entry.class, "getValue", Object.class), mapEntry), JsonNode.class);

loopCreator.ifTrue(loopCreator.invokeVirtualMethod(ofMethod(JsonNode.class, "isNull", boolean.class), fieldValue))
.trueBranch().continueScope(loopCreator);
BytecodeCreator fieldReader = loopCreator
.ifTrue(loopCreator.invokeVirtualMethod(ofMethod(JsonNode.class, "isNull", boolean.class), fieldValue))
.falseBranch();

ResultHandle fieldName = fieldReader
.invokeInterfaceMethod(ofMethod(Map.Entry.class, "getKey", Object.class), mapEntry);
Switch.StringSwitch strSwitch = fieldReader.stringSwitch(fieldName);

Set<String> deserializedFields = new HashSet<>();
ResultHandle deserializationContext = deserialize.getMethodParam(1);
Switch.StringSwitch strSwitch = loopCreator.stringSwitch(fieldName);
return deserializeFields(classCreator, classInfo, deserializationContext, objHandle, fieldValue, deserializedFields,
return deserializeFields(classCreator, classInfo, deserialize.getMethodParam(1), objHandle, fieldValue, new HashSet<>(),
strSwitch, parseTypeParameters(classInfo, classCreator));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.quarkus.resteasy.reactive.jackson.deployment.test;

import java.util.Map;

public class MapWrapper {

private String name;
private Map<String, String> properties;

public MapWrapper() {
}

public MapWrapper(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Map<String, String> getProperties() {
return properties;
}

public void setProperties(Map<String, String> properties) {
this.properties = properties;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ public StateRecord echoDog(StateRecord stateRecord) {
return stateRecord;
}

@POST
@Path("/null-map-echo")
@Consumes(MediaType.APPLICATION_JSON)
public MapWrapper echoNullMap(MapWrapper mapWrapper) {
return mapWrapper;
}

@EnableSecureSerialization
@GET
@Path("/abstract-cat")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public JavaArchive get() {
AbstractPet.class, Dog.class, Cat.class, Veterinarian.class, AbstractNamedPet.class,
AbstractUnsecuredPet.class, UnsecuredPet.class, SecuredPersonInterface.class, Frog.class,
Pond.class, FrogBodyParts.class, FrogBodyParts.BodyPart.class, ContainerDTO.class,
NestedInterface.class, StateRecord.class)
NestedInterface.class, StateRecord.class, MapWrapper.class)
.addAsResource(new StringAsset("admin-expression=admin\n" +
"user-expression=user\n" +
"birth-date-roles=alice,bob\n"), "application.properties");
Expand Down Expand Up @@ -733,4 +733,18 @@ public void testRecordEcho() {
assertTrue(first >= 0);
assertEquals(first, last);
}

@Test
public void testNullMapEcho() {
RestAssured
.with()
.body(new MapWrapper("test"))
.contentType("application/json; charset=utf-8")
.post("/simple/null-map-echo")
.then()
.statusCode(200)
.contentType("application/json")
.body("name", Matchers.is("test"))
.body("properties", Matchers.nullValue());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public JavaArchive get() {
AbstractPet.class, Dog.class, Cat.class, Veterinarian.class, AbstractNamedPet.class,
AbstractUnsecuredPet.class, UnsecuredPet.class, SecuredPersonInterface.class, Frog.class,
Pond.class, FrogBodyParts.class, FrogBodyParts.BodyPart.class, ContainerDTO.class,
NestedInterface.class, StateRecord.class)
NestedInterface.class, StateRecord.class, MapWrapper.class)
.addAsResource(new StringAsset("admin-expression=admin\n" +
"user-expression=user\n" +
"birth-date-roles=alice,bob\n" +
Expand Down
Loading