Mercurial > hg > orthanc
changeset 3679:6358923d3ced
C-FIND: forbid wildcard matching on some VRs, ignore main tags below the queried level
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 20 Feb 2020 20:06:19 +0100 |
parents | 26c6d47467a9 |
children | 453c0ece560a |
files | OrthancServer/Search/DatabaseLookup.cpp OrthancServer/ServerContext.cpp |
diffstat | 2 files changed, 63 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancServer/Search/DatabaseLookup.cpp Thu Feb 20 20:00:02 2020 +0100 +++ b/OrthancServer/Search/DatabaseLookup.cpp Thu Feb 20 20:06:19 2020 +0100 @@ -198,8 +198,26 @@ AddConstraint(constraint.release()); } - else if (dicomQuery.find('*') != std::string::npos || - dicomQuery.find('?') != std::string::npos) + else if ( + /** + * New test in Orthanc 1.6.0: Wild card matching is only allowed + * for a subset of value representations: AE, CS, LO, LT, PN, + * SH, ST, UC, UR, UT. + * http://dicom.nema.org/medical/dicom/2019e/output/chtml/part04/sect_C.2.2.2.4.html + **/ + (vr == ValueRepresentation_ApplicationEntity || // AE + vr == ValueRepresentation_CodeString || // CS + vr == ValueRepresentation_LongString || // LO + vr == ValueRepresentation_LongText || // LT + vr == ValueRepresentation_PersonName || // PN + vr == ValueRepresentation_ShortString || // SH + vr == ValueRepresentation_ShortText || // ST + vr == ValueRepresentation_UnlimitedCharacters || // UC + vr == ValueRepresentation_UniversalResource || // UR + vr == ValueRepresentation_UnlimitedText // UT + ) && + (dicomQuery.find('*') != std::string::npos || + dicomQuery.find('?') != std::string::npos)) { AddConstraint(new DicomTagConstraint (tag, ConstraintType_Wildcard, dicomQuery, caseSensitive, mandatoryTag));
--- a/OrthancServer/ServerContext.cpp Thu Feb 20 20:00:02 2020 +0100 +++ b/OrthancServer/ServerContext.cpp Thu Feb 20 20:06:19 2020 +0100 @@ -801,7 +801,8 @@ size_t since, size_t limit) { - unsigned int databaseLimit = (queryLevel == ResourceType_Instance ? limitFindInstances_ : limitFindResults_); + unsigned int databaseLimit = (queryLevel == ResourceType_Instance ? + limitFindInstances_ : limitFindResults_); std::vector<std::string> resources, instances; @@ -815,6 +816,11 @@ LOG(INFO) << "Number of candidate resources after fast DB filtering on main DICOM tags: " << resources.size(); + /** + * "resources" contains the Orthanc ID of the resource at level + * "queryLevel", "instances" contains one the Orthanc ID of one + * sample instance from this resource. + **/ assert(resources.size() == instances.size()); size_t countResults = 0; @@ -839,12 +845,47 @@ // Case (1): The main DICOM tags, as stored in the database, // are sufficient to look for match - if (!GetIndex().GetAllMainDicomTags(dicom, instances[i])) + DicomMap tmp; + if (!GetIndex().GetAllMainDicomTags(tmp, instances[i])) { // The instance has been removed during the execution of the // lookup, ignore it continue; } + +#if 1 + // New in Orthanc 1.6.0: Only keep the main DICOM tags at the + // level of interest for the query + switch (queryLevel) + { + // WARNING: Don't reorder cases below, and don't add "break" + case ResourceType_Instance: + dicom.MergeMainDicomTags(tmp, ResourceType_Instance); + + case ResourceType_Series: + dicom.MergeMainDicomTags(tmp, ResourceType_Series); + + case ResourceType_Study: + dicom.MergeMainDicomTags(tmp, ResourceType_Study); + + case ResourceType_Patient: + dicom.MergeMainDicomTags(tmp, ResourceType_Patient); + break; + + default: + throw OrthancException(ErrorCode_InternalError); + } + + // Special case of the "Modality" at the study level, in order + // to deal with C-FIND on "ModalitiesInStudy" (0008,0061). + // Check out integration test "test_rest_modalities_in_study". + if (queryLevel == ResourceType_Study) + { + dicom.CopyTagIfExists(tmp, DICOM_TAG_MODALITY); + } +#else + dicom.Assign(tmp); // This emulates Orthanc <= 1.5.8 +#endif hasOnlyMainDicomTags = true; }