Avoid a crash encoding contained bundle (#1778)

* Avoid a crash encoding contained bundle

* Add changelog

* Apply same fix to XML

* Fix typo
This commit is contained in:
James Agnew 2020-03-25 21:20:10 -04:00 committed by GitHub
parent 4b5165b5e2
commit b794618e9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 84 additions and 10 deletions

View File

@ -317,19 +317,14 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
}
case CONTAINED_RESOURCE_LIST:
case CONTAINED_RESOURCES: {
/*
* Disabled per #103 ContainedDt value = (ContainedDt) theNextValue; for (IResource next :
* value.getContainedResources()) { if (getContainedResources().getResourceId(next) != null) { continue; }
* encodeResourceToJsonStreamWriter(theResDef, next, theWriter, null, true,
* fixContainedResourceId(next.getId().getValue())); }
*/
List<IBaseResource> containedResources = getContainedResources().getContainedResources();
if (containedResources.size() > 0) {
beginArray(theEventWriter, theChildName);
for (IBaseResource next : containedResources) {
IIdType resourceId = getContainedResources().getResourceId(next);
encodeResourceToJsonStreamWriter(theResDef, next, theEventWriter, null, true, fixContainedResourceId(resourceId.getValue()), theEncodeContext);
String value = resourceId.getValue();
encodeResourceToJsonStreamWriter(theResDef, next, theEventWriter, null, true, fixContainedResourceId(value), theEncodeContext);
}
theEventWriter.endArray();
@ -359,7 +354,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
RuntimeResourceDefinition def = myContext.getResourceDefinition(resource);
theEncodeContext.pushPath(def.getName(), true);
encodeResourceToJsonStreamWriter(def, resource, theEventWriter, theChildName, false, theEncodeContext);
encodeResourceToJsonStreamWriter(def, resource, theEventWriter, theChildName, theContainedResource, theEncodeContext);
theEncodeContext.popPath();
break;

View File

@ -287,7 +287,8 @@ public class XmlParser extends BaseParser {
for (IBaseResource next : getContainedResources().getContainedResources()) {
IIdType resourceId = getContainedResources().getResourceId(next);
theEventWriter.writeStartElement("contained");
encodeResourceToXmlStreamWriter(next, theEventWriter, true, fixContainedResourceId(resourceId.getValue()), theEncodeContext);
String value = resourceId.getValue();
encodeResourceToXmlStreamWriter(next, theEventWriter, true, fixContainedResourceId(value), theEncodeContext);
theEventWriter.writeEndElement();
}
break;
@ -300,7 +301,7 @@ public class XmlParser extends BaseParser {
}
theEventWriter.writeStartElement(theChildName);
theEncodeContext.pushPath(resourceName, true);
encodeResourceToXmlStreamWriter(resource, theEventWriter, false, theEncodeContext);
encodeResourceToXmlStreamWriter(resource, theEventWriter, theIncludedResource, theEncodeContext);
theEncodeContext.popPath();
theEventWriter.writeEndElement();
break;

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 1778
title: "When encoding a resource, a crash could occur if the resource had a contained Bundle resource. This
is not commonly done, but there are valid scenarios for doing so."

View File

@ -789,6 +789,40 @@ public class JsonParserR4Test extends BaseTest {
return b;
}
/**
* Ensure that a contained bundle doesn't cause a crash
*/
@Test
public void testEncodeContainedBundle() {
String auditEvent = "{\n" +
" \"resourceType\": \"AuditEvent\",\n" +
" \"contained\": [ {\n" +
" \"resourceType\": \"Bundle\",\n" +
" \"id\": \"REASONS\",\n" +
" \"entry\": [ {\n" +
" \"resource\": {\n" +
" \"resourceType\": \"Condition\",\n" +
" \"id\": \"123\"\n" +
" }\n" +
" } ]\n" +
" }, {\n" +
" \"resourceType\": \"MeasureReport\",\n" +
" \"id\": \"MRPT5000602611RD\",\n" +
" \"evaluatedResource\": [ {\n" +
" \"reference\": \"#REASONS\"\n" +
" } ]\n" +
" } ],\n" +
" \"entity\": [ {\n" +
" \"what\": {\n" +
" \"reference\": \"#MRPT5000602611RD\"\n" +
" }\n" +
" } ]\n" +
"}";
AuditEvent ae = ourCtx.newJsonParser().parseResource(AuditEvent.class, auditEvent);
String auditEventAsString = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(ae);
assertEquals(auditEvent, auditEventAsString);
}
@AfterClass
public static void afterClassClearContext() {

View File

@ -9,6 +9,7 @@ import static org.junit.Assert.assertThat;
import ca.uhn.fhir.test.BaseTest;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.AuditEvent;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Composition;
import org.hl7.fhir.r4.model.DocumentReference;
@ -115,5 +116,43 @@ public class XmlParserR4Test extends BaseTest {
ourLog.info(encoded);
}
/**
* Ensure that a contained bundle doesn't cause a crash
*/
@Test
public void testEncodeContainedBundle() {
String auditEvent = "<AuditEvent xmlns=\"http://hl7.org/fhir\">\n" +
" <contained>\n" +
" <Bundle xmlns=\"http://hl7.org/fhir\">\n" +
" <id value=\"REASONS\"/>\n" +
" <entry>\n" +
" <resource>\n" +
" <Condition xmlns=\"http://hl7.org/fhir\">\n" +
" <id value=\"123\"/>\n" +
" </Condition>\n" +
" </resource>\n" +
" </entry>\n" +
" </Bundle>\n" +
" </contained>\n" +
" <contained>\n" +
" <MeasureReport xmlns=\"http://hl7.org/fhir\">\n" +
" <id value=\"MRPT5000602611RD\"/>\n" +
" <evaluatedResource>\n" +
" <reference value=\"#REASONS\"/>\n" +
" </evaluatedResource>\n" +
" </MeasureReport>\n" +
" </contained>\n" +
" <entity>\n" +
" <what>\n" +
" <reference value=\"#MRPT5000602611RD\"/>\n" +
" </what>\n" +
" </entity>\n" +
"</AuditEvent>";
AuditEvent ae = ourCtx.newXmlParser().parseResource(AuditEvent.class, auditEvent);
String auditEventAsString = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(ae);
assertEquals(auditEvent, auditEventAsString);
}
}