Reject invalid param prefix.

An unrecognized param prefix had been silently ignored.
Reject it with a DataFormatException instead.
This commit is contained in:
Michael Buckley 2021-02-04 10:34:03 -05:00
parent 3dac899e3a
commit 50acfbede3
3 changed files with 68 additions and 30 deletions

View File

@ -20,6 +20,8 @@ package ca.uhn.fhir.rest.param;
* #L% * #L%
*/ */
import ca.uhn.fhir.parser.DataFormatException;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isBlank;
public abstract class BaseParamWithPrefix<T extends BaseParam> extends BaseParam { public abstract class BaseParamWithPrefix<T extends BaseParam> extends BaseParam {
@ -58,8 +60,9 @@ public abstract class BaseParamWithPrefix<T extends BaseParam> extends BaseParam
if (!isBlank(prefix)) { if (!isBlank(prefix)) {
myPrefix = ParamPrefixEnum.forValue(prefix); myPrefix = ParamPrefixEnum.forValue(prefix);
if (myPrefix == null) { if (myPrefix == null) {
// prefix doesn't match standard values. Try legacy values
switch (prefix) { switch (prefix) {
case ">=": case ">=":
myPrefix = ParamPrefixEnum.GREATERTHAN_OR_EQUALS; myPrefix = ParamPrefixEnum.GREATERTHAN_OR_EQUALS;
@ -77,14 +80,9 @@ public abstract class BaseParamWithPrefix<T extends BaseParam> extends BaseParam
myPrefix = ParamPrefixEnum.APPROXIMATE; myPrefix = ParamPrefixEnum.APPROXIMATE;
break; break;
default : default :
ourLog.warn("Invalid prefix being ignored: {}", prefix); throw new DataFormatException("Invalid prefix: \"" + prefix + "\"");
break;
} }
ourLog.warn("Date parameter has legacy prefix '{}' which has been removed from FHIR. This should be replaced with '{}'", prefix, myPrefix.getValue());
if (myPrefix != null) {
ourLog.warn("Date parameter has legacy prefix '{}' which has been removed from FHIR. This should be replaced with '{}'", prefix, myPrefix);
}
} }
} }
@ -107,4 +105,5 @@ public abstract class BaseParamWithPrefix<T extends BaseParam> extends BaseParam
myPrefix = thePrefix; myPrefix = thePrefix;
return (T) this; return (T) this;
} }
} }

View File

@ -0,0 +1,61 @@
package ca.uhn.fhir.rest.param;
import ca.uhn.fhir.parser.DataFormatException;
import org.junit.jupiter.api.Test;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import static org.junit.jupiter.api.Assertions.*;
public class DateParamTest {
@Test
public void testBasicParse() {
DateParam input = new DateParam("2020-01-01");
// too bad value is a j.u.Date instead of a new JSR-310 type
// DataParam parses using default tz, so go backwards.
ZonedDateTime zonedDateTime = input.getValue().toInstant().atZone(ZoneId.systemDefault());
assertEquals(2020,zonedDateTime.getYear());
assertEquals(Month.JANUARY,zonedDateTime.getMonth());
assertEquals(1,zonedDateTime.getDayOfMonth());
assertNull(input.getPrefix());
}
@Test
public void testBadDateFormat() {
try {
DateParam input = new DateParam("09-30-1960");
fail();
} catch (DataFormatException e) {
// expected
}
}
@Test
public void testPrefixParse() {
DateParam input = new DateParam("gt2020-01-01");
assertEquals(ParamPrefixEnum.GREATERTHAN, input.getPrefix());
}
@Test
public void testLegacyPrefixParse() {
DateParam input = new DateParam(">2020-01-01");
assertEquals(ParamPrefixEnum.GREATERTHAN, input.getPrefix());
}
@Test
public void testJunkDateIssue1465() {
// Issue 1464 - the string "junk" wasn't returning 400 as expected. Parsed as a prefix instead, and discarded.
try {
DateParam input = new DateParam("junk");
fail();
} catch (DataFormatException e) {
// expected
}
}
}

View File

@ -5163,28 +5163,6 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
} }
} }
@Test
public void testIssueDateFormatError1465() {
try {
SearchParameterMap map = SearchParameterMap.newSynchronous();
map.add("birthdate", new DateParam("09-30-1960"));
myPatientDao.search(map);
fail();
} catch (DataFormatException e) {
assertEquals("Invalid date/time format: \"09-30-1960\"", e.getMessage());
}
try {
SearchParameterMap map = SearchParameterMap.newSynchronous();
map.add("birthdate", new DateParam("junk"));
myPatientDao.search(map);
fail();
} catch (DataFormatException e) {
assertEquals("Invalid date/time format: \"junk\"", e.getMessage());
}
}
@Test @Test
public void testDateSearchParametersShouldBeTimezoneIndependent() { public void testDateSearchParametersShouldBeTimezoneIndependent() {