From Johannes Lange:
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 24 Nov 2010 16:35:23 +0000 (16:35 +0000)
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 24 Nov 2010 16:35:23 +0000 (16:35 +0000)
Function dissect_per_bit_string_display might read more bytes than available (PER dissector).
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5394

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

epan/dissectors/packet-per.c

index 9c4a120098b00ea52e0ee3e47c32d91b0c0b60a5..59c431d63a027653738342054d6a7a5560a7f189 100644 (file)
@@ -2063,17 +2063,35 @@ static tvbuff_t *dissect_per_bit_string_display(tvbuff_t *tvb, guint32 offset, a
                                proto_item_append_text(actx->created_item, ", %u LSB pad bits", pad_length);
                        }
                }
-               
-               if (length<=64) {
-                       if (length<=8)
-                               value = tvb_get_bits8(tvb, offset, length);
-                       else if (length<=16)
-                               value = tvb_get_bits16(tvb, offset, length, FALSE);
-                       else if (length<=32)
-                               value = tvb_get_bits32(tvb, offset, length, FALSE);
-                       else
-                               value = tvb_get_bits64(tvb, offset, length, FALSE);
-                       
+                
+               if (length<=64) { /* if read into 64 bits also handle length <= 24, 40, 48, 56 bits */
+                       if (length<=8) {
+                               value = tvb_get_bits8(out_tvb, 0, length);
+                       }else if (length<=16) {
+                               value = tvb_get_bits16(out_tvb, 0, length, FALSE);
+                       }else if (length<=24) { /* first read 16 and then the remaining bits */
+                               value = tvb_get_bits16(out_tvb, 0, 16, FALSE);
+                               value <<= 8;
+                               value |= tvb_get_bits8(out_tvb, 16, length - 16);
+                       }else if (length<=32) {
+                               value = tvb_get_bits32(out_tvb, 0, length, FALSE);
+                       }else if (length<=40) { /* first read 32 and then the remaining bits */
+                               value = tvb_get_bits32(out_tvb, 0, 32, FALSE);
+                               value <<= 8;
+                               value |= tvb_get_bits8(out_tvb, 32, length - 32);
+                       }else if (length<=48) { /* first read 32 and then the remaining bits */
+                               value = tvb_get_bits32(out_tvb, 0, 32, FALSE);
+                               value <<= 16;
+                               value |= tvb_get_bits16(out_tvb, 32, length - 32, FALSE);
+                       }else if (length<=56) { /* first read 32 and 16 then the remaining bits */
+                               value = tvb_get_bits32(out_tvb, 0, 32, FALSE);
+                               value <<= 16;
+                               value |= tvb_get_bits16(out_tvb, 32, 16, FALSE);
+                               value <<= 8;
+                               value |= tvb_get_bits8(out_tvb, 48, length - 48);
+                       }else {
+                               value = tvb_get_bits64(out_tvb, 0, length, FALSE);
+                       }
                        if (actx->aligned){
                                proto_item_append_text(actx->created_item, ", %s decimal value %" G_GINT64_MODIFIER "u", 
                                        decode_bits_in_field(pad_length, length, value), value);