Fix NPE in validator and add more validation for bad references

This commit is contained in:
Grahame Grieve 2020-09-01 09:43:21 +10:00
parent 2867e20a42
commit 89b0e0a32b
3 changed files with 21 additions and 3 deletions

View File

@ -331,6 +331,7 @@ public class I18nConstants {
public static final String REFERENCE_REF_NOTFOUND_BUNDLE = "Reference_REF_NotFound_Bundle";
public static final String REFERENCE_REF_NOTYPE = "Reference_REF_NoType";
public static final String REFERENCE_REF_RESOURCETYPE = "Reference_REF_ResourceType";
public static final String REFERENCE_REF_SUSPICIOUS = "REFERENCE_REF_SUSPICIOUS";
public static final String REFERENCE_REF_WRONGTARGET = "Reference_REF_WrongTarget";
public static final String REFERENCE_TO__CANNOT_BE_RESOLVED = "reference_to__cannot_be_resolved";
public static final String REFERENCE__REFERS_TO_A__NOT_A_VALUESET = "Reference__refers_to_a__not_a_ValueSet";

View File

@ -604,3 +604,4 @@ FHIRPATH_BAD_DATE = Unable to parse Date {0}
FHIRPATH_NUMERICAL_ONLY = Error evaluating FHIRPath expression: The function {0} can only be used on integer, decimal or Quantity but found {1}
FHIRPATH_DECIMAL_ONLY = Error evaluating FHIRPath expression: The function {0} can only be used on a decimal but found {1}
FHIRPATH_FOCUS_PLURAL = Error evaluating FHIRPath expression: focus for {0} has more than one value
REFERENCE_REF_SUSPICIOUS = The syntax of the reference ''{0}'' looks incorrect, and it should be checked

View File

@ -2398,6 +2398,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
// special known URLs that can't be validated but are known to be valid
return;
}
warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, !isSuspiciousReference(ref), I18nConstants.REFERENCE_REF_SUSPICIOUS, ref);
ResolvedReference we = localResolve(ref, stack, errors, path, (Element) hostContext.getAppContext(), element);
String refType;
@ -2439,10 +2440,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
String ft;
if (we != null)
if (we != null) {
ft = we.getType();
else
} else {
ft = tryParse(ref);
}
if (reference.hasType()) { // R4 onwards...
// the type has to match the specified
@ -2596,6 +2598,20 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
}
private boolean isSuspiciousReference(String url) {
if (!assumeValidRestReferences || url == null || Utilities.isAbsoluteUrl(url)) {
return false;
}
String[] parts = url.split("\\/");
if (parts.length == 2 && context.getResourceNames().contains(parts[0]) && Utilities.isValidId(parts[1])) {
return false;
}
if (parts.length == 4 && context.getResourceNames().contains(parts[0]) && Utilities.isValidId(parts[1]) && "_history".equals(parts[2]) && Utilities.isValidId(parts[3])) {
return false;
}
return true;
}
private String asListByUrl(Collection<StructureDefinition> list) {
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
for (StructureDefinition sd : list) {
@ -4842,7 +4858,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
case 2:
return checkResourceType(parts[0]);
default:
if (parts[parts.length - 2].equals("_history"))
if (parts[parts.length - 2].equals("_history") && parts.length >= 4)
return checkResourceType(parts[parts.length - 4]);
else
return checkResourceType(parts[parts.length - 2]);