Browse Source

view services do not fail

Stasik0 8 years ago
parent
commit
2d87556063
2 changed files with 49 additions and 1 deletions
  1. 37 0
      include/ua_types.h
  2. 12 1
      src/server/ua_services_view.c

+ 37 - 0
include/ua_types.h

@@ -339,6 +339,37 @@ UA_NodeId_isNull(const UA_NodeId *p) {
             p->identifier.numeric == 0);
 }
 
+static UA_INLINE UA_Boolean
+UA_NodeId_isEmptyString(const UA_NodeId *p) {
+    return (p->namespaceIndex == 0 &&
+            p->identifierType == UA_NODEIDTYPE_STRING &&
+            p->identifier.string.length == 0);
+}
+
+static UA_INLINE UA_Boolean
+UA_NodeId_isEmptyGUID(const UA_NodeId *p) {
+    return (p->namespaceIndex == 0 &&
+            p->identifierType == UA_NODEIDTYPE_GUID &&
+            p->identifier.guid.data1 == 0 &&
+            p->identifier.guid.data2 == 0 &&
+            p->identifier.guid.data3 == 0 &&
+            p->identifier.guid.data4[0] == 0 &&
+            p->identifier.guid.data4[1] == 0 &&
+            p->identifier.guid.data4[2] == 0 &&
+            p->identifier.guid.data4[3] == 0 &&
+            p->identifier.guid.data4[4] == 0 &&
+            p->identifier.guid.data4[5] == 0 &&
+            p->identifier.guid.data4[6] == 0 &&
+            p->identifier.guid.data4[7] == 0);
+}
+
+static UA_INLINE UA_Boolean
+UA_NodeId_isEmptyByteString(const UA_NodeId *p) {
+    return (p->namespaceIndex == 0 &&
+            p->identifierType == UA_NODEIDTYPE_BYTESTRING &&
+            p->identifier.byteString.length == 0);
+}
+
 UA_Boolean UA_EXPORT UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2);
 
 /** The following functions are shorthand for creating NodeIds. */
@@ -440,6 +471,12 @@ typedef struct {
     UA_String name;
 } UA_QualifiedName;
 
+static UA_INLINE UA_Boolean
+UA_QualifiedName_isNull(const UA_QualifiedName *q) {
+    return (q->namespaceIndex == 0 &&
+            q->name.length == 0);
+}
+
 static UA_INLINE UA_QualifiedName
 UA_QUALIFIEDNAME(UA_UInt16 nsIndex, char *chars) {
     UA_QualifiedName qn; qn.namespaceIndex = nsIndex;

+ 12 - 1
src/server/ua_services_view.c

@@ -459,7 +459,7 @@ walkBrowsePath(UA_Server *server, UA_Session *session, const UA_Node *node, cons
     UA_NodeId *reftypes = NULL;
     size_t reftypes_count = 1; // all_refs or no subtypes => 1
     UA_Boolean all_refs = false;
-    if(UA_NodeId_isNull(&elem->referenceTypeId))
+    if(UA_NodeId_isNull(&elem->referenceTypeId) || UA_NodeId_isEmptyString(&elem->referenceTypeId) || UA_NodeId_isEmptyGUID(&elem->referenceTypeId) || UA_NodeId_isEmptyByteString(&elem->referenceTypeId))
         all_refs = true;
     else if(!elem->includeSubtypes)
         reftypes = (UA_NodeId*)(uintptr_t)&elem->referenceTypeId; // ptr magic due to const cast
@@ -529,6 +529,15 @@ void Service_TranslateBrowsePathsToNodeIds_single(UA_Server *server, UA_Session
         return;
     }
         
+    //relativePath elements should not have an empty targetName
+    for(size_t i=0;i<path->relativePath.elementsSize;i++){
+        UA_QualifiedName *qname = &(path->relativePath.elements[i].targetName);
+        if(UA_QualifiedName_isNull(qname)){
+            result->statusCode = UA_STATUSCODE_BADBROWSENAMEINVALID;
+            return;
+        }
+    }
+
     size_t arraySize = 10;
     result->targets = UA_malloc(sizeof(UA_BrowsePathTarget) * arraySize);
     if(!result->targets) {
@@ -543,10 +552,12 @@ void Service_TranslateBrowsePathsToNodeIds_single(UA_Server *server, UA_Session
         result->targets = NULL;
         return;
     }
+
     result->statusCode = walkBrowsePath(server, session, firstNode, &path->relativePath, 0,
                                         &result->targets, &arraySize, &result->targetsSize);
     if(result->targetsSize == 0 && result->statusCode == UA_STATUSCODE_GOOD)
         result->statusCode = UA_STATUSCODE_BADNOMATCH;
+
     if(result->statusCode != UA_STATUSCODE_GOOD) {
         UA_Array_delete(result->targets, result->targetsSize, &UA_TYPES[UA_TYPES_BROWSEPATHTARGET]);
         result->targets = NULL;