Wireshark-dev: [Wireshark-dev] Patch for OPC UA protocol
From: Gerhard Gappmeier <gerhard.gappmeier@xxxxxxxxxxx>
Date: Mon, 15 Nov 2010 13:54:56 +0100
Hello 

I attached a patch which fixes some problems in the array handling of OPC UA 
data when the array length is zero or -1 which is a Null-Array.

-- 
mit freundlichen Grüßen / best regards

*Gerhard Gappmeier*
ascolab GmbH - automation systems communication laboratory
Tel.: +49 9131 691 123
Fax: +49 9131 691 128
Web: http://www.ascolab.com
GPG Key Id: 5AAC50C4
GPG Fingerprint: 967A 15F1 2788 164D CCA3 6C46 07CD 6F82 5AAC 50C4

--
*ascolab GmbH*
Geschäftsführer: Gerhard Gappmeier, Matthias Damm, Uwe Steinkrauß
Sitz der Gesellschaft: Am Weichselgarten 7 . 91058 Erlangen . Germany
Registernummer: HRB 9360
Registergericht: Amtsgericht Fürth
Index: plugins/opcua/opcua_simpletypes.c
===================================================================
--- plugins/opcua/opcua_simpletypes.c	(revision 34874)
+++ plugins/opcua/opcua_simpletypes.c	(working copy)
@@ -556,15 +556,16 @@
     proto_tree *subtree = proto_item_add_subtree(ti, ett_opcua_variant);
     gint    iOffset = *pOffset;
     guint8  EncodingMask;
-    gint32  ArrayLength;
+    gint32  ArrayLength = 0;
 
     EncodingMask = tvb_get_guint8(tvb, iOffset);
     proto_tree_add_item(subtree, hf_opcua_variant_encodingmask, tvb, iOffset, 1, TRUE);
     iOffset++;
-    ArrayLength = tvb_get_letohl(tvb, iOffset);
 
     if (EncodingMask & VARIANT_ARRAYMASK)
     {
+        ArrayLength = tvb_get_letohl(tvb, iOffset);
+
         /* type is encoded in bits 0-5 */
         switch(EncodingMask & 0x3f)
         {
@@ -595,6 +596,28 @@
         case OpcUaType_DataValue: parseArrayComplex(subtree, tvb, &iOffset, "DataValue", parseDataValue); break;
         case OpcUaType_Variant: parseArrayComplex(subtree, tvb, &iOffset, "Variant", parseVariant); break;
         }
+
+        if (EncodingMask & VARIANT_ARRAYDIMENSIONS)
+        {
+            proto_item *ti_2 = proto_tree_add_text(tree, tvb, 0, -1, "Array Dimensions");
+            proto_tree *subtree_2 = proto_item_add_subtree(ti_2, ett_opcua_array);
+            int i;
+
+            if (ArrayLength < MAX_ARRAY_LEN)
+            {
+                for (i=0; i<ArrayLength; i++)
+                {
+                    parseInt32(subtree_2, tvb, pOffset, hf_opcua_Int32);
+                }
+            }
+            else
+            {
+                proto_item *pi;
+                /* XXX - This should be expert_add_info_format, but we need pinfo for that */
+                pi = proto_tree_add_text(tree, tvb, iOffset, 4, "Array length %d too large to process", ArrayLength);
+                PROTO_ITEM_SET_GENERATED(pi);
+            }
+        }
     }
     else
     {
@@ -630,28 +653,6 @@
         }
     }
 
-    if (EncodingMask & VARIANT_ARRAYDIMENSIONS)
-    {
-        proto_item *ti_2 = proto_tree_add_text(tree, tvb, 0, -1, "Array Dimensions");
-        proto_tree *subtree_2 = proto_item_add_subtree(ti_2, ett_opcua_array);
-        int i;
-
-        if (ArrayLength < MAX_ARRAY_LEN)
-        {
-            for (i=0; i<ArrayLength; i++)
-            {
-                parseInt32(subtree_2, tvb, pOffset, hf_opcua_Int32);
-            }
-        }
-        else
-        {
-	    proto_item *pi;
-            /* XXX - This should be expert_add_info_format, but we need pinfo for that */
-            pi = proto_tree_add_text(tree, tvb, iOffset, 4, "Array length %d too large to process", ArrayLength);
-	    PROTO_ITEM_SET_GENERATED(pi);
-        }
-    }
-
     *pOffset = iOffset;
 }
 
@@ -671,9 +672,6 @@
     iLen = tvb_get_letohl(tvb, *pOffset);
     proto_tree_add_item(subtree, hf_opcua_ArraySize, tvb, *pOffset, 4, TRUE);
 
-    if (iLen == -1) return; /* no array */
-    if (iLen == 0)  return; /* array with zero elements*/
-
     if (iLen > MAX_ARRAY_LEN)
     {
 	proto_item *pi;
@@ -705,9 +703,6 @@
     iLen = tvb_get_letohl(tvb, *pOffset);
     proto_tree_add_item(subtree, hf_opcua_ArraySize, tvb, *pOffset, 4, TRUE);
 
-    if (iLen == -1) return; /* no array */
-    if (iLen == 0)  return; /* array with zero elements*/
-
     if (iLen > MAX_ARRAY_LEN)
     {
 	proto_item *pi;
@@ -738,9 +733,6 @@
     iLen = tvb_get_letohl(tvb, *pOffset);
     proto_tree_add_item(subtree, hf_opcua_ArraySize, tvb, *pOffset, 4, TRUE);
 
-    if (iLen == -1) return; /* no array */
-    if (iLen == 0)  return; /* array with zero elements*/
-
     if (iLen > MAX_ARRAY_LEN)
     {
 	proto_item *pi;