Fix crash in JSON parser when parsing extensions on primitive elements

This commit is contained in:
James Agnew 2018-01-18 09:07:23 +07:00
parent 2c65f1c81b
commit 3644151a69
4 changed files with 99 additions and 16 deletions

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.parser;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -33,7 +33,6 @@ import ca.uhn.fhir.parser.json.*;
import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType;
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.util.BinaryUtil;
import ca.uhn.fhir.util.ElementUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@ -275,12 +274,12 @@ 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())); }
*/
/*
* 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);
@ -982,7 +981,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
for (int i = 0; i < nextArray.size(); i++) {
JsonLikeValue nextObject = nextArray.get(i);
JsonLikeValue nextAlternate = null;
if (nextAlternateArray != null) {
if (nextAlternateArray != null && nextAlternateArray.size() >= (i + 1)) {
nextAlternate = nextAlternateArray.get(i);
}
parseChildren(theState, theName, nextObject, nextAlternate, theAlternateName, true);
@ -1066,12 +1065,12 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
}
}
/*
* This happens if an element has an extension but no actual value. I.e.
* if a resource has a "_status" element but no corresponding "status"
* element. This could be used to handle a null value with an extension
* for example.
*/
/*
* This happens if an element has an extension but no actual value. I.e.
* if a resource has a "_status" element but no corresponding "status"
* element. This could be used to handle a null value with an extension
* for example.
*/
if (allUnderscoreNames > handledUnderscoreNames) {
for (String alternateName : nextExtObj.keySet()) {
if (alternateName.startsWith("_") && alternateName.length() > 1) {

View File

@ -3,13 +3,17 @@ package ca.uhn.fhir.parser;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.util.TestUtil;
import com.google.common.collect.Sets;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Extension;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.StringType;
import org.junit.AfterClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
@ -21,6 +25,19 @@ public class JsonParserR4Test {
private static final Logger ourLog = LoggerFactory.getLogger(JsonParserR4Test.class);
private static FhirContext ourCtx = FhirContext.forR4();
@Test
public void testParseExtensionOnPrimitive() throws IOException {
String input = IOUtils.toString(JsonParserR4Test.class.getResourceAsStream("/extension-on-line.txt"));
IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);
Patient pt = parser.parseResource(Patient.class, input);
StringType line0 = pt.getAddressFirstRep().getLine().get(0);
assertEquals("535 Sheppard Avenue West, Unit 1907", line0.getValue());
Extension houseNumberExt = line0.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-houseNumber");
assertEquals("535", ((StringType)houseNumberExt.getValue()).getValue());
}
@Test
public void testExcludeNothing() {
IParser parser = ourCtx.newJsonParser().setPrettyPrint(true);

View File

@ -0,0 +1,58 @@
{
"resourceType": "Patient",
"name": [
{
"family": "Doe",
"given": [
"John",
"W."
]
}
],
"gender": "male",
"birthDate": "2012-02-14",
"address": [
{
"use": "home",
"line": [
"535 Sheppard Avenue West, Unit 1907",
"RR 66, Station A, RPO 123"
],
"_line": [
{
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-houseNumber",
"valueString": "535"
},
{
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-streetName",
"valueString": "Sheppard"
},
{
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-streetNameType",
"valueString": "Avenue"
},
{
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-direction",
"valueString": "West"
},
{
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-unitID",
"valueString": "1907"
},
{
"url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-postBox",
"valueString": "1234"
}
]
}
],
"city": "Toronto",
"state": "ON",
"postalCode": "M3H4X8"
}
]
}

View File

@ -6,6 +6,15 @@
<title>HAPI FHIR Changelog</title>
</properties>
<body>
<release version="3.3.0" date="TBD">
<action type="fix">
Fix a crash in the JSON parser when parsing extensions on repeatable
elements (e.g. Patient.address.line) where there is an extension on the
first repetion but not on subsequent repetitions of the
repeatable primitive. Thanks to Igor Sirkovich for providing a
test case!
</action>
</release>
<release version="3.2.0" date="2018-01-13">
<action type="add">
Support for custom search parameters has been backported in the JPA server