cb_array_hdr_size
authorStefan Metzmacher <metze@samba.org>
Mon, 21 Mar 2022 16:52:20 +0000 (17:52 +0100)
committerStefan Metzmacher <metze@samba.org>
Sun, 7 Aug 2022 22:17:52 +0000 (00:17 +0200)
epan/dissectors/packet-dcerpc-nt.c

index 186e80e0c80fce4c747b5a0393be515b9007e835..608fb9ef9621509645df01a38bb0fff331f78b95 100644 (file)
@@ -41,6 +41,14 @@ static gint ett_nt_data_blob = -1;
 static expert_field ei_dcerpc_nt_badsid = EI_INIT;
 
 
+static int cb_array_hdr_size(dcerpc_info *di,
+                            gboolean is_conformant, gboolean is_varying,
+                            int start_offset, int end_offset);
+static void cb_str_postprocess_options(packet_info *pinfo,
+                                      proto_item *item,
+                                      dcerpc_info *di,
+                                      gint options,
+                                      const char *s);
 
 /* This is used to safely walk the decode tree up, one item at a time safely.
    This is used by dcerpc dissectors that want to push the display of a string
@@ -272,51 +280,23 @@ static void cb_byte_array_postprocess(packet_info *pinfo, proto_tree *tree _U_,
                        void *callback_args)
 {
        gint options = GPOINTER_TO_INT(callback_args);
-       gint levels = CB_STR_ITEM_LEVELS(options);
        char *s;
-       int conformance_size = 4;
        int hdr_size;
 
-       if (di->call_data->flags & DCERPC_IS_NDR64) {
-               conformance_size = 8;
-       }
-
-       /* Align start_offset on 4-byte boundary. */
-
-       if (start_offset % conformance_size)
-               start_offset += conformance_size - (start_offset % conformance_size);
-
-       /* Get byte array value */
-       hdr_size = 3 * conformance_size;
-
-       if ((end_offset - start_offset) <= hdr_size)
+       hdr_size = cb_array_hdr_size(di,
+                                    TRUE, /* is_conformant */
+                                    TRUE, /* is_varying */
+                                    start_offset,
+                                    end_offset);
+       if (hdr_size < 0) {
                return;
-
-       s = tvb_bytes_to_str(pinfo->pool, tvb, start_offset + hdr_size, (end_offset - start_offset - hdr_size) );
-
-       /* Append string to COL_INFO */
-
-       if (options & CB_STR_COL_INFO) {
-               col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", s);
        }
 
-       /* Append string to upper-level proto_items */
+       start_offset += hdr_size;
 
-       if (levels > 0 && item && s && s[0]) {
-               proto_item_append_text(item, ": %s", s);
-               item = GET_ITEM_PARENT(item);
-               levels--;
-               if (levels > 0) {
-                       proto_item_append_text(item, ": %s", s);
-                       item = GET_ITEM_PARENT(item);
-                       levels--;
-                       while (levels > 0) {
-                               proto_item_append_text(item, " %s", s);
-                               item = GET_ITEM_PARENT(item);
-                               levels--;
-                       }
-               }
-       }
+       s = tvb_bytes_to_str(pinfo->pool, tvb, start_offset, end_offset - start_offset);
+
+       cb_str_postprocess_options(pinfo, item, di, options, s);
 }
 
 int
@@ -1199,6 +1179,37 @@ dissect_ndr_uint16s(tvbuff_t *tvb, gint offset, packet_info *pinfo,
                                      tree, drep, hfindex, length);
 }
 
+static int cb_array_hdr_size(dcerpc_info *di,
+                            gboolean is_conformant, gboolean is_varying,
+                            int start_offset, int end_offset)
+{
+       int orig_offset = start_offset;
+       gint8 conformance_size = 4;
+       int hdr_size = 0;
+
+       DISSECTOR_ASSERT(is_conformant || is_varying);
+
+       if (di->call_data->flags & DCERPC_IS_NDR64) {
+               conformance_size = 8;
+       }
+
+       /* Align start_offset on 4-byte boundary. */
+
+       if (start_offset % conformance_size)
+               start_offset += conformance_size - (start_offset % conformance_size);
+
+       /* Get byte array value */
+       if (is_conformant)
+               hdr_size += conformance_size;
+       if (is_varying)
+               hdr_size += (2*conformance_size);
+
+       if ((end_offset - start_offset) <= hdr_size)
+               return -1;
+
+       return start_offset - orig_offset;
+}
+
 static void cb_str_postprocess_options(packet_info *pinfo,
                                       proto_item *item,
                                       dcerpc_info *di,
@@ -1246,17 +1257,19 @@ void cb_wstr_postprocess(packet_info *pinfo, proto_tree *tree _U_,
                        void *callback_args)
 {
        gint options = GPOINTER_TO_INT(callback_args);
-       char *s;
-
-       /* Align start_offset on 4-byte boundary. */
-
-       if (start_offset % 4)
-               start_offset += 4 - (start_offset % 4);
+       guint8 *s;
+       int hdr_size;
 
-       /* Get string value */
+       hdr_size = cb_array_hdr_size(di,
+                                    TRUE, /* is_conformant */
+                                    TRUE, /* is_varying */
+                                    start_offset,
+                                    end_offset);
+       if (hdr_size < 0) {
+               return;
+       }
 
-       if ((end_offset - start_offset) <= 12)
-               return;         /* XXX: Use unistr2 dissector instead? */
+       start_offset += hdr_size;
 
        /*
         * XXX - need to handle non-printable characters here.
@@ -1267,10 +1280,10 @@ void cb_wstr_postprocess(packet_info *pinfo, proto_tree *tree _U_,
         * efforts of that routine?
         */
        s = tvb_get_string_enc(pinfo->pool,
-               tvb, start_offset + 12, end_offset - start_offset - 12,
+               tvb, start_offset, end_offset - start_offset,
                ENC_UTF_16|ENC_LITTLE_ENDIAN);
 
-       cb_str_postprocess_options(pinfo, item, di, options, s);
+       cb_str_postprocess_options(pinfo, item, di, options, (char *)s);
 }
 
 void cb_str_postprocess(packet_info *pinfo, proto_tree *tree _U_,
@@ -1280,16 +1293,18 @@ void cb_str_postprocess(packet_info *pinfo, proto_tree *tree _U_,
 {
        gint options = GPOINTER_TO_INT(callback_args);
        guint8 *s;
+       int hdr_size;
 
-       /* Align start_offset on 4-byte boundary. */
-
-       if (start_offset % 4)
-               start_offset += 4 - (start_offset % 4);
-
-       /* Get string value */
+       hdr_size = cb_array_hdr_size(di,
+                                    TRUE, /* is_conformant */
+                                    TRUE, /* is_varying */
+                                    start_offset,
+                                    end_offset);
+       if (hdr_size < 0) {
+               return;
+       }
 
-       if ((end_offset - start_offset) <= 12)
-               return;         /* XXX: Use unistr2 dissector instead? */
+       start_offset += hdr_size;
 
        /*
         * XXX - need to handle non-printable characters here.
@@ -1300,9 +1315,9 @@ void cb_str_postprocess(packet_info *pinfo, proto_tree *tree _U_,
         * efforts of that routine?
         */
        s = tvb_get_string_enc(pinfo->pool,
-               tvb, start_offset + 12, (end_offset - start_offset - 12), ENC_ASCII);
+               tvb, start_offset, end_offset - start_offset, ENC_ASCII);
 
-       cb_str_postprocess_options(pinfo, item, di, options, s);
+       cb_str_postprocess_options(pinfo, item, di, options, (char *)s);
 }
 
 /* Dissect a pointer to a NDR string and append the string value to the