More tvb_get_nstringz0() fixes. Timo Sirainen pointed out that Bad
authorgerald <gerald@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 19 May 2003 03:23:12 +0000 (03:23 +0000)
committergerald <gerald@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 19 May 2003 03:23:12 +0000 (03:23 +0000)
Things can happen if we pass a zero buffer length to tvb_get_nstringz0().
Throw an exception if this happens.

In various dissectors make sure the tvb_get_nstringz0()'s buffer length
is greater than zero.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@7688 f5534014-38df-0310-8fa8-9805f1628bb7

epan/proto.c
epan/tvbuff.c
epan/tvbuff.h
packet-aim.c
packet-fix.c
packet-ppp.c
packet-quake.c
packet-quake2.c
packet-quake3.c
packet-quakeworld.c
packet-scsi.c

index 28fab40d817df0b94cee8b70d50fbb7cc4a0f567..4738c6de4858b1a6c51593ef13dbd9450a084c56 100644 (file)
@@ -1,7 +1,7 @@
 /* proto.c
  * Routines for protocol tree
  *
- * $Id: proto.c,v 1.85 2003/05/03 01:11:29 guy Exp $
+ * $Id: proto.c,v 1.86 2003/05/19 03:23:12 gerald Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -698,31 +698,32 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
                        break;
 
                case FT_STRINGZ:
-                       if (length == -1) {
-                               /* This can throw an exception */
-                               length = tvb_strsize(tvb, start);
+                       if (length != 0) {  /* XXX - Should we throw an exception instead? */
+                               if (length == -1) {
+                                       /* This can throw an exception */
+                                       length = tvb_strsize(tvb, start);
 
-                               /* This g_strdup'ed memory is freed in proto_tree_free_node() */
-                               string = g_malloc(length);
+                                       /* This g_strdup'ed memory is freed in proto_tree_free_node() */
+                                       string = g_malloc(length);
 
-                               tvb_memcpy(tvb, string, start, length);
-                               new_fi->length = length;
-                       }
-                       else {
-                               /* In this case, length signifies maximum length. */
+                                       tvb_memcpy(tvb, string, start, length);
+                                       new_fi->length = length;
+                               }
+                               else {
+                                       /* In this case, length signifies maximum length. */
 
-                               /* This g_strdup'ed memory is freed in proto_tree_free_node() */
-                               string = g_malloc(length);
+                                       /* This g_strdup'ed memory is freed in proto_tree_free_node() */
+                                       string = g_malloc(length);
 
-                               CLEANUP_PUSH(g_free, string);
+                                       CLEANUP_PUSH(g_free, string);
 
-                               found_length = tvb_get_nstringz0(tvb, start, length, string);
+                                       found_length = tvb_get_nstringz0(tvb, start, length, string);
 
-                               CLEANUP_POP;
-                               new_fi->length = found_length + 1;
+                                       CLEANUP_POP;
+                                       new_fi->length = found_length + 1;
+                               }
+                               proto_tree_set_string(new_fi, string, TRUE);
                        }
-                       proto_tree_set_string(new_fi, string, TRUE);
-
                        break;
 
                case FT_UINT_STRING:
index 033102bf1dc943fb165b4730e00baa5317c7b5b5..19853e3aeb5e9f64b73cfe185b5a56778589135b 100644 (file)
@@ -9,7 +9,7 @@
  *             the data of a backing tvbuff, or can be a composite of
  *             other tvbuffs.
  *
- * $Id: tvbuff.c,v 1.43 2003/04/30 02:35:23 gerald Exp $
+ * $Id: tvbuff.c,v 1.44 2003/05/19 03:23:12 gerald Exp $
  *
  * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
  *
@@ -1783,6 +1783,8 @@ tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
  * have a terminating NUL. If the string was truncated when copied into buffer,
  * a NUL is placed at the end of buffer to terminate it.
+ *
+ * bufsize MUST be greater than 0.
  */
 gint
 tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
@@ -1791,6 +1793,10 @@ tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint bufsize, guint8* buffer)
 
        len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
 
+       if (len == 0) {
+               THROW(BoundsError);
+       }
+
        if (len == -1) {
                buffer[bufsize - 1] = 0;
                return bytes_copied - 1;
index 4e1b9de59b529af7981781c89346fdd3886a422d..5a08bac7b537eff892cfd28edec3e0cebe6f120f 100644 (file)
@@ -9,7 +9,7 @@
  *             the data of a backing tvbuff, or can be a composite of
  *             other tvbuffs.
  *
- * $Id: tvbuff.h,v 1.31 2003/04/30 02:35:23 gerald Exp $
+ * $Id: tvbuff.h,v 1.32 2003/05/19 03:23:12 gerald Exp $
  *
  * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
  *
@@ -337,6 +337,8 @@ extern gint tvb_get_nstringz(tvbuff_t *tvb, gint offset, guint bufsize,
 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
  * have a terminating NUL. If the string was truncated when copied into buffer,
  * a NUL is placed at the end of buffer to terminate it.
+ *
+ * bufsize MUST be greater than 0.
  */
 extern gint tvb_get_nstringz0(tvbuff_t *tvb, gint offset, guint bufsize,
     guint8* buffer);
index b2a65df1e4ac365321156d6d92aa98bdcbf815f7..bf059f5a2de5eb732022deb7572057b1602f1d92 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for AIM Instant Messenger (OSCAR) dissection
  * Copyright 2000, Ralf Hoelzer <ralf@well.com>
  *
- * $Id: packet-aim.c,v 1.28 2003/05/11 02:40:36 guy Exp $
+ * $Id: packet-aim.c,v 1.29 2003/05/19 03:23:10 gerald Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -1742,8 +1742,8 @@ static int dissect_aim_tlv(tvbuff_t *tvb, packet_info *pinfo _U_,
     
     /* Show the info in the top of the tree if it's one of the standard
        data types */
-    if (tmp[i].datatype == FT_STRING) {
-      guint8 *buf;      
+    if (tmp[i].datatype == FT_STRING && length > 0) {
+      guint8 *buf;
       buf = g_malloc(length);
       tvb_get_nstringz0(tvb, offset + 4, length, buf);
       ti1 = proto_tree_add_text(tree, tvb, offset, length + 4, 
index 281ddbd1ec73eae12e5120765282fc66a906805c..75cf54810eda0f210ad656a5aafc2f0954e9de80 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for Financial Information eXchange (FIX) Protocol dissection
  * Copyright 2000, PC Drew <drewpc@ibsncentral.com>
  *
- * $Id: packet-fix.c,v 1.2 2003/04/30 02:35:19 gerald Exp $
+ * $Id: packet-fix.c,v 1.3 2003/05/19 03:23:11 gerald Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -878,6 +878,9 @@ dissect_fix(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
     value_offset = equals + 1;
     value_len = ctrla_offset - value_offset;
+    if (value_len < 1) {
+        return return_malformed_packet(tvb, pinfo, tree);
+    }
 
     value = g_malloc(value_len);
     tvb_get_nstringz0(tvb, value_offset, value_len, value);
@@ -918,6 +921,9 @@ dissect_fix(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
             value_len = ctrla_offset - value_offset;
 
             tag_len = equals - field_offset;
+            if (tag_len < 1 || value_len < 1) {
+                return return_malformed_packet(tvb, pinfo, tree);
+            }
             tag_str = g_malloc(tag_len);
             tvb_get_nstringz0(tvb, field_offset, tag_len, tag_str);
             tag = atoi(tag_str);
index 04558334ae9adc3fa2605d964639c7cc4632a1a7..b94d9bf145ceb05023856cd8b87a3a9c69dee959 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-ppp.c
  * Routines for ppp packet disassembly
  *
- * $Id: packet-ppp.c,v 1.110 2003/04/29 17:56:48 guy Exp $
+ * $Id: packet-ppp.c,v 1.111 2003/05/19 03:23:11 gerald Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -2202,7 +2202,7 @@ dissect_bap_phone_delta_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                          tvb_get_guint8(tvb, offset + 2));
       break;
     case BAP_PHONE_DELTA_SUBOPT_SUBSC_NUM:
-      if (subopt_len >= 2) {
+      if (subopt_len > 2) {
         tvb_get_nstringz0(tvb, offset + 2, subopt_len - 2, buf);
         proto_tree_add_text(suboption_tree, tvb, offset + 2, subopt_len - 2,
                          "Subscriber Number: %s", buf);
@@ -2212,9 +2212,11 @@ dissect_bap_phone_delta_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
       }
       break;
     case BAP_PHONE_DELTA_SUBOPT_PHONENUM_SUBADDR:
-      tvb_get_nstringz0(tvb, offset + 2, subopt_len - 2, buf);
-      proto_tree_add_text(suboption_tree, tvb, offset + 2, subopt_len - 2,
+      if (subopt_len > 2) {
+        tvb_get_nstringz0(tvb, offset + 2, subopt_len - 2, buf);
+        proto_tree_add_text(suboption_tree, tvb, offset + 2, subopt_len - 2,
                          "Phone Number Sub Address: %s", buf);
+      }
       break;
     default:
       proto_tree_add_text(suboption_tree, tvb, offset + 2, subopt_len - 2,
@@ -2234,9 +2236,11 @@ dissect_bap_reason_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
   guint8 buf[256];     /* Since length field in BAP Reason Option is
                           8 bits, 256-octets buf is large enough */
 
-  tvb_get_nstringz0(tvb, offset + 2, length - 2, buf);
-  proto_tree_add_text(tree, tvb, offset, length, "%s: %s",
+  if (length > 2) {
+    tvb_get_nstringz0(tvb, offset + 2, length - 2, buf);
+    proto_tree_add_text(tree, tvb, offset, length, "%s: %s",
                           optp->name, buf);
+  }
 }
 
 static void
index a5beb3abc80ec3e41e0b00e5c4f1e37289132a94..52cc1f4a5914ef522f256c8446e4580b492e9773 100644 (file)
@@ -4,7 +4,7 @@
  * Uwe Girlich <uwe@planetquake.com>
  *     http://www.idsoftware.com/q1source/q1source.zip
  *
- * $Id: packet-quake.c,v 1.28 2002/08/28 21:00:26 jmayer Exp $
+ * $Id: packet-quake.c,v 1.29 2003/05/19 03:23:11 gerald Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -155,13 +155,11 @@ static void
 dissect_quake_CCREQ_CONNECT
 (tvbuff_t *tvb, proto_tree *tree)
 {
-       gint maxbufsize;
        char game[QUAKE_MAXSTRING];
        guint8 version;
        gint len;
 
-       maxbufsize = MIN(sizeof(game), tvb_length(tvb));
-       len = tvb_get_nstringz0(tvb, 0, maxbufsize, game);
+       len = tvb_get_nstringz0(tvb, 0, sizeof(game), game);
        version = tvb_get_guint8(tvb, len + 1);
 
        if (tree) {
@@ -177,13 +175,11 @@ static void
 dissect_quake_CCREQ_SERVER_INFO
 (tvbuff_t *tvb, proto_tree *tree)
 {
-       gint maxbufsize;
        char game[QUAKE_MAXSTRING];
        guint8 version;
        gint len;
 
-       maxbufsize = MIN(sizeof(game), tvb_length(tvb));
-       len = tvb_get_nstringz0(tvb, 0, maxbufsize, game);
+       len = tvb_get_nstringz0(tvb, 0, sizeof(game), game);
        version = tvb_get_guint8(tvb, len + 1);
 
        if (tree) {
@@ -214,11 +210,9 @@ dissect_quake_CCREQ_RULE_INFO
 (tvbuff_t *tvb, proto_tree *tree)
 {
        char rule[QUAKE_MAXSTRING];
-       gint maxbufsize;
        gint len;
 
-       maxbufsize = MIN(sizeof(rule), tvb_length(tvb));
-       len = tvb_get_nstringz0(tvb, 0, maxbufsize, rule);
+       len = tvb_get_nstringz0(tvb, 0, sizeof(rule), rule);
        if (tree) {
                proto_tree_add_string(tree, hf_quake_CCREQ_RULE_INFO_lastrule,
                        tvb, 0, len + 1, rule);
@@ -250,12 +244,10 @@ static void
 dissect_quake_CCREP_REJECT
 (tvbuff_t *tvb, proto_tree *tree)
 {
-       gint maxbufsize;
        char reason[QUAKE_MAXSTRING];
        gint len;
 
-       maxbufsize = MIN(sizeof(reason), tvb_length(tvb));
-       len = tvb_get_nstringz0(tvb, 0, maxbufsize, reason);
+       len = tvb_get_nstringz0(tvb, 0, sizeof(reason), reason);
 
        if (tree) {
                proto_tree_add_string(tree, hf_quake_CCREP_REJECT_reason,
@@ -270,7 +262,6 @@ dissect_quake_CCREP_SERVER_INFO
 {
        gint offset;
        gint len;
-       gint maxbufsize;
        char address[QUAKE_MAXSTRING];
        char server[QUAKE_MAXSTRING];
        char map[QUAKE_MAXSTRING];
@@ -281,24 +272,21 @@ dissect_quake_CCREP_SERVER_INFO
 
        offset = 0;
 
-       maxbufsize = MIN((int)sizeof(address), tvb_length_remaining(tvb, offset));
-       len = tvb_get_nstringz0(tvb, offset, maxbufsize, address);
+       len = tvb_get_nstringz0(tvb, offset, sizeof(address), address);
        if (tree) {
                proto_tree_add_string(tree, hf_quake_CCREP_SERVER_INFO_address,
                        tvb, offset, len + 1, address);
        }
        offset += len + 1;
 
-       maxbufsize = MIN((int)sizeof(server), tvb_length_remaining(tvb, offset));
-       len = tvb_get_nstringz0(tvb, offset, maxbufsize, server);
+       len = tvb_get_nstringz0(tvb, offset, sizeof(server), server);
        if (tree) {
                proto_tree_add_string(tree, hf_quake_CCREP_SERVER_INFO_server,
                        tvb, offset, len + 1, server);
        }
        offset += len + 1;
 
-       maxbufsize = MIN((int)sizeof(map), tvb_length_remaining(tvb, offset));
-       len = tvb_get_nstringz0(tvb, offset, maxbufsize, map);
+       len = tvb_get_nstringz0(tvb, offset, sizeof(map), map);
        if (tree) {
                proto_tree_add_string(tree, hf_quake_CCREP_SERVER_INFO_map,
                        tvb, offset, len + 1, map);
@@ -327,7 +315,6 @@ dissect_quake_CCREP_PLAYER_INFO
        gint offset;
        guint8 player;
        gint len;
-       gint maxbufsize;
        char name[QUAKE_MAXSTRING];
        guint32 colors;
        guint32 color_shirt;
@@ -345,8 +332,7 @@ dissect_quake_CCREP_PLAYER_INFO
        }
        offset += 1;
 
-       maxbufsize = MIN((int)sizeof(name), tvb_length_remaining(tvb, offset));
-       len = tvb_get_nstringz0(tvb, offset, maxbufsize, name);
+       len = tvb_get_nstringz0(tvb, offset, sizeof(name), name);
        if (tree) {
                proto_tree_add_string(tree, hf_quake_CCREP_PLAYER_INFO_name,
                        tvb, offset, len + 1, name);
@@ -382,8 +368,7 @@ dissect_quake_CCREP_PLAYER_INFO
        }
        offset += 3*4;
 
-       maxbufsize = MIN((int)sizeof(address), tvb_length_remaining(tvb, offset));
-       len = tvb_get_nstringz0(tvb, offset, maxbufsize, address);
+       len = tvb_get_nstringz0(tvb, offset, sizeof(address), address);
        if (tree) {
                proto_tree_add_string(tree, hf_quake_CCREP_PLAYER_INFO_address,
                        tvb, offset, len + 1, address);
@@ -398,7 +383,6 @@ dissect_quake_CCREP_RULE_INFO
 {
        char rule[QUAKE_MAXSTRING];
        char value[QUAKE_MAXSTRING];
-       gint maxbufsize;
        gint len;
        gint offset;
 
@@ -406,16 +390,14 @@ dissect_quake_CCREP_RULE_INFO
 
        offset = 0;
 
-       maxbufsize = MIN((int)sizeof(rule), tvb_length_remaining(tvb, offset));
-       len = tvb_get_nstringz0(tvb, offset, maxbufsize, rule);
+       len = tvb_get_nstringz0(tvb, offset, sizeof(rule), rule);
        if (tree) {
                proto_tree_add_string(tree, hf_quake_CCREP_RULE_INFO_rule,
                        tvb, offset, len + 1, rule);
        }
        offset += len + 1;
 
-       maxbufsize = MIN((int)sizeof(value), tvb_length_remaining(tvb, offset));
-       len = tvb_get_nstringz0(tvb, offset, maxbufsize, value);
+       len = tvb_get_nstringz0(tvb, offset, sizeof(value), value);
        if (tree) {
                proto_tree_add_string(tree, hf_quake_CCREP_RULE_INFO_value,
                        tvb, offset, len + 1, value);
index 5babdcf7373784cf858044cd4ec902d550bb63c1..f62665cf9cf8feb82c09828320958fbd9beaa688 100644 (file)
@@ -7,7 +7,7 @@
  *     http://www.dgs.monash.edu.au/~timf/bottim/
  *     http://www.opt-sci.Arizona.EDU/Pandora/default.asp
  *
- * $Id: packet-quake2.c,v 1.13 2002/08/28 21:00:27 jmayer Exp $
+ * $Id: packet-quake2.c,v 1.14 2003/05/19 03:23:11 gerald Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -93,7 +93,6 @@ dissect_quake2_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo _U_,
        proto_tree      *cl_tree = NULL;
        proto_item      *cl_item = NULL;
        guint8          text[2048];
-       int             maxbufsize = 0;
        int             len;
        int             offset;
 
@@ -116,8 +115,7 @@ dissect_quake2_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo _U_,
        /* all the rest of the packet is just text */
         offset = 4;
 
-        maxbufsize = MIN((gint)sizeof(text), tvb_length_remaining(tvb, offset));
-        len = tvb_get_nstringz0(tvb, offset, maxbufsize, text);
+        len = tvb_get_nstringz0(tvb, offset, sizeof(text), text);
         if (cl_tree) {
                 proto_tree_add_string(cl_tree, hf_quake2_connectionless_text,
                         tvb, offset, len + 1, text);
@@ -351,9 +349,7 @@ dissect_quake2_client_commands_uinfo(tvbuff_t *tvb, packet_info *pinfo _U_,
        guint8 message[MAX_MSGLEN];
        gint len;
 
-       len = tvb_get_nstringz0(tvb, 0,
-                       (guint) MIN(tvb_reported_length(tvb), sizeof(message)),
-                       message);
+       len = tvb_get_nstringz0(tvb, 0, sizeof(message), message);
 
        if (message[len] == '\0')
                len++;
@@ -372,9 +368,7 @@ dissect_quake2_client_commands_stringcmd(tvbuff_t *tvb, packet_info *pinfo _U_,
        guint8 message[MAX_MSGLEN];
        gint len;
 
-       len = tvb_get_nstringz0(tvb, 0,
-                       (guint) MIN(tvb_reported_length(tvb), sizeof(message)),
-                       message);
+       len = tvb_get_nstringz0(tvb, 0, sizeof(message), message);
 
        if (message[len] == '\0')
                len++;
index eb0c4a5b5192f976d1d5b2d120a75257b4ff1766..1255e581c54fc12c8beede71fe8fe57be36ffa9a 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Uwe Girlich <uwe@planetquake.com>
  *
- * $Id: packet-quake3.c,v 1.14 2002/08/28 21:00:27 jmayer Exp $
+ * $Id: packet-quake3.c,v 1.15 2003/05/19 03:23:11 gerald Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -174,8 +174,7 @@ dissect_quake3_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo _U_,
        /* all the rest of the packet is just text */
        offset = 4;
 
-       maxbufsize = MIN((gint)sizeof(text), tvb_length_remaining(tvb, offset));
-       len = tvb_get_nstringz0(tvb, offset, maxbufsize, text);
+       len = tvb_get_nstringz0(tvb, offset, sizeof(text), text);
         if (cl_tree) {
                text_item = proto_tree_add_string(cl_tree,
                                hf_quake3_connectionless_text,
index 7df768925d98320a54ed2cfa4e15641fcbb806f3..b10ef583483d0e529b1963eba106c801ee229fe5 100644 (file)
@@ -4,7 +4,7 @@
  * Uwe Girlich <uwe@planetquake.com>
  *     http://www.idsoftware.com/q1source/q1source.zip
  *
- * $Id: packet-quakeworld.c,v 1.16 2002/08/28 21:00:28 jmayer Exp $
+ * $Id: packet-quakeworld.c,v 1.17 2003/05/19 03:23:11 gerald Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -385,8 +385,7 @@ dissect_quakeworld_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo,
        /* all the rest of the packet is just text */
         offset = 4;
 
-        maxbufsize = MIN((gint)MAX_TEXT_SIZE, tvb_length_remaining(tvb, offset));
-        len = tvb_get_nstringz0(tvb, offset, maxbufsize, text);
+        len = tvb_get_nstringz0(tvb, offset, sizeof(text), text);
        /* actually, we should look for a eol char and stop already there */
 
         if (cl_tree) {
index 5853d38c81df298d125559ed7cc6be479384c2bd..6d72348e2969858844fd28527b411e7119862c4c 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for decoding SCSI CDBs and responses
  * Author: Dinesh G Dutt (ddutt@cisco.com)
  *
- * $Id: packet-scsi.c,v 1.29 2003/04/30 02:35:19 gerald Exp $
+ * $Id: packet-scsi.c,v 1.30 2003/05/19 03:23:11 gerald Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
@@ -1500,9 +1500,11 @@ dissect_scsi_evpd (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
             }
             break;
         case SCSI_EVPD_DEVSERNUM:
-            tvb_get_nstringz0 (tvb, offset, MIN(plen, sizeof(str)), str);
-            proto_tree_add_text (evpd_tree, tvb, offset, plen,
+           if (plen > 0) {
+              tvb_get_nstringz0 (tvb, offset, MIN(plen, sizeof(str)), str);
+              proto_tree_add_text (evpd_tree, tvb, offset, plen,
                                  "Product Serial Number: %s", str);
+            }
             break;
         }
     }