GSMTAP: add definitions for new LTE RRC channels
[metze/wireshark/wip.git] / epan / tvbuff.c
1 /* tvbuff.c
2  *
3  * Testy, Virtual(-izable) Buffer of guint8*'s
4  *
5  * "Testy" -- the buffer gets mad when an attempt to access data
6  *              beyond the bounds of the buffer. An exception is thrown.
7  *
8  * "Virtual" -- the buffer can have its own data, can use a subset of
9  *              the data of a backing tvbuff, or can be a composite of
10  *              other tvbuffs.
11  *
12  * Copyright (c) 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
13  *
14  * Code to convert IEEE floating point formats to native floating point
15  * derived from code Copyright (c) Ashok Narayanan, 2000
16  *
17  * Wireshark - Network traffic analyzer
18  * By Gerald Combs <gerald@wireshark.org>
19  * Copyright 1998 Gerald Combs
20  *
21  * SPDX-License-Identifier: GPL-2.0-or-later
22  */
23
24 #include "config.h"
25
26 #include <string.h>
27 #include <stdio.h>
28 #include <errno.h>
29
30 #include "wsutil/pint.h"
31 #include "wsutil/sign_ext.h"
32 #include "wsutil/unicode-utils.h"
33 #include "wsutil/nstime.h"
34 #include "wsutil/time_util.h"
35 #include "tvbuff.h"
36 #include "tvbuff-int.h"
37 #include "strutil.h"
38 #include "to_str.h"
39 #include "charsets.h"
40 #include "proto.h"      /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
41 #include "exceptions.h"
42
43 /*
44  * Just make sure we include the prototype for strptime as well
45  * (needed for glibc 2.2) but make sure we do this only if not
46  * yet defined.
47  */
48 #include <time.h>
49 /*#ifndef HAVE_STRPTIME*/
50 #ifndef strptime
51 #include "wsutil/strptime.h"
52 #endif
53  /*#endif*/
54
55 static guint64
56 _tvb_get_bits64(tvbuff_t *tvb, guint bit_offset, const gint total_no_of_bits);
57
58 static inline gint
59 _tvb_captured_length_remaining(const tvbuff_t *tvb, const gint offset);
60
61 static inline const guint8*
62 ensure_contiguous(tvbuff_t *tvb, const gint offset, const gint length);
63
64 static inline guint8 *
65 tvb_get_raw_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint length);
66
67 tvbuff_t *
68 tvb_new(const struct tvb_ops *ops)
69 {
70         tvbuff_t *tvb;
71         gsize     size = ops->tvb_size;
72
73         g_assert(size >= sizeof(*tvb));
74
75         tvb = (tvbuff_t *) g_slice_alloc(size);
76
77         tvb->next                = NULL;
78         tvb->ops                 = ops;
79         tvb->initialized         = FALSE;
80         tvb->flags               = 0;
81         tvb->length              = 0;
82         tvb->reported_length     = 0;
83         tvb->contained_length    = 0;
84         tvb->real_data           = NULL;
85         tvb->raw_offset          = -1;
86         tvb->ds_tvb              = NULL;
87
88         return tvb;
89 }
90
91 static void
92 tvb_free_internal(tvbuff_t *tvb)
93 {
94         gsize     size;
95
96         DISSECTOR_ASSERT(tvb);
97
98         if (tvb->ops->tvb_free)
99                 tvb->ops->tvb_free(tvb);
100
101         size = tvb->ops->tvb_size;
102
103         g_slice_free1(size, tvb);
104 }
105
106 /* XXX: just call tvb_free_chain();
107  *      Not removed so that existing dissectors using tvb_free() need not be changed.
108  *      I'd argue that existing calls to tvb_free() should have actually beeen
109  *      calls to tvb_free_chain() although the calls were OK as long as no
110  *      subsets, etc had been created on the tvb. */
111 void
112 tvb_free(tvbuff_t *tvb)
113 {
114         tvb_free_chain(tvb);
115 }
116
117 void
118 tvb_free_chain(tvbuff_t  *tvb)
119 {
120         tvbuff_t *next_tvb;
121         DISSECTOR_ASSERT(tvb);
122         while (tvb) {
123                 next_tvb = tvb->next;
124                 tvb_free_internal(tvb);
125                 tvb  = next_tvb;
126         }
127 }
128
129 tvbuff_t *
130 tvb_new_chain(tvbuff_t *parent, tvbuff_t *backing)
131 {
132         tvbuff_t *tvb = tvb_new_proxy(backing);
133
134         tvb_add_to_chain(parent, tvb);
135         return tvb;
136 }
137
138 void
139 tvb_add_to_chain(tvbuff_t *parent, tvbuff_t *child)
140 {
141         tvbuff_t *tmp = child;
142
143         DISSECTOR_ASSERT(parent);
144         DISSECTOR_ASSERT(child);
145
146         while (child) {
147                 tmp   = child;
148                 child = child->next;
149
150                 tmp->next    = parent->next;
151                 parent->next = tmp;
152         }
153 }
154
155 /*
156  * Check whether that offset goes more than one byte past the
157  * end of the buffer.
158  *
159  * If not, return 0; otherwise, return exception
160  */
161 static inline int
162 validate_offset(const tvbuff_t *tvb, const guint abs_offset)
163 {
164         if (G_LIKELY(abs_offset <= tvb->length)) {
165                 /* It's OK. */
166                 return 0;
167         }
168
169         /*
170          * It's not OK, but why?  Which boundaries is it
171          * past?
172          */
173         if (abs_offset <= tvb->contained_length) {
174                 /*
175                  * It's past the captured length, but not past
176                  * the reported end of any parent tvbuffs from
177                  * which this is constructed, or the reported
178                  * end of this tvbuff, so it's out of bounds
179                  * solely because we're past the end of the
180                  * captured data.
181                  */
182                 return BoundsError;
183         }
184
185         /*
186          * There's some actual packet boundary, not just the
187          * artificial boundary imposed by packet slicing, that
188          * we're past.
189          */
190         if (abs_offset <= tvb->reported_length) {
191                 /*
192                  * We're within the bounds of what this tvbuff
193                  * purportedly contains, based on some length
194                  * value, but we're not within the bounds of
195                  * something from which this tvbuff was
196                  * extracted, so that length value ran past
197                  * the end of some parent tvbuff.
198                  */
199                 return ContainedBoundsError;
200         }
201
202         /*
203          * OK, we're past the bounds of what this tvbuff
204          * purportedly contains.
205          */
206         if (tvb->flags & TVBUFF_FRAGMENT) {
207                 /*
208                  * This tvbuff is the first fragment of a larger
209                  * packet that hasn't been reassembled, so we
210                  * assume that's the source of the prblem - if
211                  * we'd reassembled the packet, we wouldn't
212                  * have gone past the end.
213                  *
214                  * That might not be true, but for at least
215                  * some forms of reassembly, such as IP
216                  * reassembly, you don't know how big the
217                  * reassembled packet is unless you reassemble
218                  * it, so, in those cases, we can't determine
219                  * whether we would have gone past the end
220                  * had we reassembled the packet.
221                  */
222                 return FragmentBoundsError;
223         }
224
225         /*
226          * OK, it looks as if we ran past the claimed length
227          * of data.
228          */
229         return ReportedBoundsError;
230 }
231
232 static inline int
233 compute_offset(const tvbuff_t *tvb, const gint offset, guint *offset_ptr)
234 {
235         if (offset >= 0) {
236                 /* Positive offset - relative to the beginning of the packet. */
237                 if (G_LIKELY((guint) offset <= tvb->length)) {
238                         *offset_ptr = offset;
239                 } else if ((guint) offset <= tvb->contained_length) {
240                         return BoundsError;
241                 } else if ((guint) offset <= tvb->reported_length) {
242                         return ContainedBoundsError;
243                 } else if (tvb->flags & TVBUFF_FRAGMENT) {
244                         return FragmentBoundsError;
245                 } else {
246                         return ReportedBoundsError;
247                 }
248         }
249         else {
250                 /* Negative offset - relative to the end of the packet. */
251                 if (G_LIKELY((guint) -offset <= tvb->length)) {
252                         *offset_ptr = tvb->length + offset;
253                 } else if ((guint) -offset <= tvb->contained_length) {
254                         return BoundsError;
255                 } else if ((guint) -offset <= tvb->reported_length) {
256                         return ContainedBoundsError;
257                 } else if (tvb->flags & TVBUFF_FRAGMENT) {
258                         return FragmentBoundsError;
259                 } else {
260                         return ReportedBoundsError;
261                 }
262         }
263
264         return 0;
265 }
266
267 static inline int
268 compute_offset_and_remaining(const tvbuff_t *tvb, const gint offset, guint *offset_ptr, guint *rem_len)
269 {
270         int exception;
271
272         exception = compute_offset(tvb, offset, offset_ptr);
273         if (!exception)
274                 *rem_len = tvb->length - *offset_ptr;
275
276         return exception;
277 }
278
279 /* Computes the absolute offset and length based on a possibly-negative offset
280  * and a length that is possible -1 (which means "to the end of the data").
281  * Returns integer indicating whether the offset is in bounds (0) or
282  * not (exception number). The integer ptrs are modified with the new offset,
283  * captured (available) length, and contained length (amount that's present
284  * in the parent tvbuff based on its reported length).
285  * No exception is thrown; on success, we return 0, otherwise we return an
286  * exception for the caller to throw if appropriate.
287  *
288  * XXX - we return success (0), if the offset is positive and right
289  * after the end of the tvbuff (i.e., equal to the length).  We do this
290  * so that a dissector constructing a subset tvbuff for the next protocol
291  * will get a zero-length tvbuff, not an exception, if there's no data
292  * left for the next protocol - we want the next protocol to be the one
293  * that gets an exception, so the error is reported as an error in that
294  * protocol rather than the containing protocol.  */
295 static inline int
296 check_offset_length_no_exception(const tvbuff_t *tvb,
297                                  const gint offset, gint const length_val,
298                                  guint *offset_ptr, guint *length_ptr)
299 {
300         guint end_offset;
301         int   exception;
302
303         DISSECTOR_ASSERT(offset_ptr);
304         DISSECTOR_ASSERT(length_ptr);
305
306         /* Compute the offset */
307         exception = compute_offset(tvb, offset, offset_ptr);
308         if (exception)
309                 return exception;
310
311         if (length_val < -1) {
312                 /* XXX - ReportedBoundsError? */
313                 return BoundsError;
314         }
315
316         /* Compute the length */
317         if (length_val == -1)
318                 *length_ptr = tvb->length - *offset_ptr;
319         else
320                 *length_ptr = length_val;
321
322         /*
323          * Compute the offset of the first byte past the length.
324          */
325         end_offset = *offset_ptr + *length_ptr;
326
327         /*
328          * Check for an overflow
329          */
330         if (end_offset < *offset_ptr)
331                 return BoundsError;
332
333         return validate_offset(tvb, end_offset);
334 }
335
336 /* Checks (+/-) offset and length and throws an exception if
337  * either is out of bounds. Sets integer ptrs to the new offset
338  * and length. */
339 static inline void
340 check_offset_length(const tvbuff_t *tvb,
341                     const gint offset, gint const length_val,
342                     guint *offset_ptr, guint *length_ptr)
343 {
344         int exception;
345
346         exception = check_offset_length_no_exception(tvb, offset, length_val, offset_ptr, length_ptr);
347         if (exception)
348                 THROW(exception);
349 }
350
351 void
352 tvb_check_offset_length(const tvbuff_t *tvb,
353                         const gint offset, gint const length_val,
354                         guint *offset_ptr, guint *length_ptr)
355 {
356         check_offset_length(tvb, offset, length_val, offset_ptr, length_ptr);
357 }
358
359 static const unsigned char left_aligned_bitmask[] = {
360         0xff,
361         0x80,
362         0xc0,
363         0xe0,
364         0xf0,
365         0xf8,
366         0xfc,
367         0xfe
368 };
369
370 tvbuff_t *
371 tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits)
372 {
373         tvbuff_t     *sub_tvb = NULL;
374         guint32       byte_offset;
375         gint32        datalen, i;
376         guint8        left, right, remaining_bits, *buf;
377         const guint8 *data;
378
379         DISSECTOR_ASSERT(tvb && tvb->initialized);
380
381         byte_offset = bit_offset >> 3;
382         left = bit_offset % 8; /* for left-shifting */
383         right = 8 - left; /* for right-shifting */
384
385         if (no_of_bits == -1) {
386                 datalen = _tvb_captured_length_remaining(tvb, byte_offset);
387                 remaining_bits = 0;
388         } else {
389                 datalen = no_of_bits >> 3;
390                 remaining_bits = no_of_bits % 8;
391                 if (remaining_bits) {
392                         datalen++;
393                 }
394         }
395
396         /* already aligned -> shortcut */
397         if ((left == 0) && (remaining_bits == 0)) {
398                 return tvb_new_subset_length_caplen(tvb, byte_offset, datalen, datalen);
399         }
400
401         DISSECTOR_ASSERT(datalen>0);
402
403         /* if at least one trailing byte is available, we must use the content
404         * of that byte for the last shift (i.e. tvb_get_ptr() must use datalen + 1
405         * if non extra byte is available, the last shifted byte requires
406         * special treatment
407         */
408         if (_tvb_captured_length_remaining(tvb, byte_offset) > datalen) {
409                 data = ensure_contiguous(tvb, byte_offset, datalen + 1); /* tvb_get_ptr */
410
411                 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
412                 buf = (guint8 *)g_malloc(datalen);
413
414                 /* shift tvb data bit_offset bits to the left */
415                 for (i = 0; i < datalen; i++)
416                         buf[i] = (data[i] << left) | (data[i+1] >> right);
417         } else {
418                 data = ensure_contiguous(tvb, byte_offset, datalen); /* tvb_get_ptr() */
419
420                 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
421                 buf = (guint8 *)g_malloc(datalen);
422
423                 /* shift tvb data bit_offset bits to the left */
424                 for (i = 0; i < (datalen-1); i++)
425                         buf[i] = (data[i] << left) | (data[i+1] >> right);
426                 buf[datalen-1] = data[datalen-1] << left; /* set last octet */
427         }
428         buf[datalen-1] &= left_aligned_bitmask[remaining_bits];
429
430         sub_tvb = tvb_new_child_real_data(tvb, buf, datalen, datalen);
431         tvb_set_free_cb(sub_tvb, g_free);
432
433         return sub_tvb;
434 }
435
436 static tvbuff_t *
437 tvb_generic_clone_offset_len(tvbuff_t *tvb, guint offset, guint len)
438 {
439         tvbuff_t *cloned_tvb;
440         guint8 *data;
441
442         DISSECTOR_ASSERT(tvb_bytes_exist(tvb, offset, len));
443
444         data = (guint8 *) g_malloc(len);
445
446         tvb_memcpy(tvb, data, offset, len);
447
448         cloned_tvb = tvb_new_real_data(data, len, len);
449         tvb_set_free_cb(cloned_tvb, g_free);
450
451         return cloned_tvb;
452 }
453
454 tvbuff_t *
455 tvb_clone_offset_len(tvbuff_t *tvb, guint offset, guint len)
456 {
457         if (tvb->ops->tvb_clone) {
458                 tvbuff_t *cloned_tvb;
459
460                 cloned_tvb = tvb->ops->tvb_clone(tvb, offset, len);
461                 if (cloned_tvb)
462                         return cloned_tvb;
463         }
464
465         return tvb_generic_clone_offset_len(tvb, offset, len);
466 }
467
468 tvbuff_t *
469 tvb_clone(tvbuff_t *tvb)
470 {
471         return tvb_clone_offset_len(tvb, 0, tvb->length);
472 }
473
474 guint
475 tvb_captured_length(const tvbuff_t *tvb)
476 {
477         DISSECTOR_ASSERT(tvb && tvb->initialized);
478
479         return tvb->length;
480 }
481
482 /* For tvbuff internal use */
483 static inline gint
484 _tvb_captured_length_remaining(const tvbuff_t *tvb, const gint offset)
485 {
486         guint abs_offset = 0, rem_length;
487         int   exception;
488
489         exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
490         if (exception)
491                 return 0;
492
493         return rem_length;
494 }
495
496 gint
497 tvb_captured_length_remaining(const tvbuff_t *tvb, const gint offset)
498 {
499         guint abs_offset = 0, rem_length;
500         int   exception;
501
502         DISSECTOR_ASSERT(tvb && tvb->initialized);
503
504         exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
505         if (exception)
506                 return 0;
507
508         return rem_length;
509 }
510
511 guint
512 tvb_ensure_captured_length_remaining(const tvbuff_t *tvb, const gint offset)
513 {
514         guint abs_offset = 0, rem_length = 0;
515         int   exception;
516
517         DISSECTOR_ASSERT(tvb && tvb->initialized);
518
519         exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
520         if (exception)
521                 THROW(exception);
522
523         if (rem_length == 0) {
524                 /*
525                  * This routine ensures there's at least one byte available.
526                  * There aren't any bytes available, so throw the appropriate
527                  * exception.
528                  */
529                 if (abs_offset < tvb->contained_length) {
530                         THROW(BoundsError);
531                 } else if (abs_offset < tvb->reported_length) {
532                         THROW(ContainedBoundsError);
533                 } else if (tvb->flags & TVBUFF_FRAGMENT) {
534                         THROW(FragmentBoundsError);
535                 } else {
536                         THROW(ReportedBoundsError);
537                 }
538         }
539         return rem_length;
540 }
541
542
543
544
545 /* Validates that 'length' bytes are available starting from
546  * offset (pos/neg). Does not throw an exception. */
547 gboolean
548 tvb_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
549 {
550         guint abs_offset = 0, abs_length;
551         int   exception;
552
553         DISSECTOR_ASSERT(tvb && tvb->initialized);
554
555         /*
556          * Negative lengths are not possible and indicate a bug (e.g. arithmetic
557          * error or an overly large value from packet data).
558          */
559         if (length < 0)
560                 return FALSE;
561
562         exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
563         if (exception)
564                 return FALSE;
565
566         return TRUE;
567 }
568
569 /* Validates that 'length' bytes, where 'length' is a 64-bit unsigned
570  * integer, are available starting from offset (pos/neg). Throws an
571  * exception if they aren't. */
572 void
573 tvb_ensure_bytes_exist64(const tvbuff_t *tvb, const gint offset, const guint64 length)
574 {
575         /*
576          * Make sure the value fits in a signed integer; if not, assume
577          * that means that it's too big.
578          */
579         if (length > G_MAXINT) {
580                 THROW(ReportedBoundsError);
581         }
582
583         /* OK, now cast it and try it with tvb_ensure_bytes_exist(). */
584         tvb_ensure_bytes_exist(tvb, offset, (gint)length);
585 }
586
587 /* Validates that 'length' bytes are available starting from
588  * offset (pos/neg). Throws an exception if they aren't. */
589 void
590 tvb_ensure_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length)
591 {
592         guint real_offset, end_offset;
593
594         DISSECTOR_ASSERT(tvb && tvb->initialized);
595
596         /*
597          * -1 doesn't mean "until end of buffer", as that's pointless
598          * for this routine.  We must treat it as a Really Large Positive
599          * Number, so that we throw an exception; we throw
600          * ReportedBoundsError, as if it were past even the end of a
601          * reassembled packet, and past the end of even the data we
602          * didn't capture.
603          *
604          * We do the same with other negative lengths.
605          */
606         if (length < 0) {
607                 THROW(ReportedBoundsError);
608         }
609
610         /* XXX: Below this point could be replaced with a call to
611          * check_offset_length with no functional change, however this is a
612          * *very* hot path and check_offset_length is not well-optimized for
613          * this case, so we eat some code duplication for a lot of speedup. */
614
615         if (offset >= 0) {
616                 /* Positive offset - relative to the beginning of the packet. */
617                 if (G_LIKELY((guint) offset <= tvb->length)) {
618                         real_offset = offset;
619                 } else if ((guint) offset <= tvb->contained_length) {
620                         THROW(BoundsError);
621                 } else if ((guint) offset <= tvb->reported_length) {
622                         THROW(ContainedBoundsError);
623                 } else if (tvb->flags & TVBUFF_FRAGMENT) {
624                         THROW(FragmentBoundsError);
625                 } else {
626                         THROW(ReportedBoundsError);
627                 }
628         }
629         else {
630                 /* Negative offset - relative to the end of the packet. */
631                 if (G_LIKELY((guint) -offset <= tvb->length)) {
632                         real_offset = tvb->length + offset;
633                 } else if ((guint) -offset <= tvb->contained_length) {
634                         THROW(BoundsError);
635                 } else if ((guint) -offset <= tvb->reported_length) {
636                         THROW(ContainedBoundsError);
637                 } else if (tvb->flags & TVBUFF_FRAGMENT) {
638                         THROW(FragmentBoundsError);
639                 } else {
640                         THROW(ReportedBoundsError);
641                 }
642         }
643
644         /*
645          * Compute the offset of the first byte past the length.
646          */
647         end_offset = real_offset + length;
648
649         /*
650          * Check for an overflow
651          */
652         if (end_offset < real_offset)
653                 THROW(BoundsError);
654
655         if (G_LIKELY(end_offset <= tvb->length))
656                 return;
657         else if (end_offset <= tvb->contained_length)
658                 THROW(BoundsError);
659         else if (end_offset <= tvb->reported_length)
660                 THROW(ContainedBoundsError);
661         else if (tvb->flags & TVBUFF_FRAGMENT)
662                 THROW(FragmentBoundsError);
663         else
664                 THROW(ReportedBoundsError);
665 }
666
667 gboolean
668 tvb_offset_exists(const tvbuff_t *tvb, const gint offset)
669 {
670         guint abs_offset = 0;
671         int   exception;
672
673         DISSECTOR_ASSERT(tvb && tvb->initialized);
674
675         exception = compute_offset(tvb, offset, &abs_offset);
676         if (exception)
677                 return FALSE;
678
679         /* compute_offset only throws an exception on >, not >= because of the
680          * comment above check_offset_length_no_exception, but here we want the
681          * opposite behaviour so we check ourselves... */
682         if (abs_offset < tvb->length) {
683                 return TRUE;
684         }
685         else {
686                 return FALSE;
687         }
688 }
689
690 guint
691 tvb_reported_length(const tvbuff_t *tvb)
692 {
693         DISSECTOR_ASSERT(tvb && tvb->initialized);
694
695         return tvb->reported_length;
696 }
697
698 gint
699 tvb_reported_length_remaining(const tvbuff_t *tvb, const gint offset)
700 {
701         guint abs_offset = 0;
702         int   exception;
703
704         DISSECTOR_ASSERT(tvb && tvb->initialized);
705
706         exception = compute_offset(tvb, offset, &abs_offset);
707         if (exception)
708                 return 0;
709
710         if (tvb->reported_length >= abs_offset)
711                 return tvb->reported_length - abs_offset;
712         else
713                 return 0;
714 }
715
716 /* Set the reported length of a tvbuff to a given value; used for protocols
717  * whose headers contain an explicit length and where the calling
718  * dissector's payload may include padding as well as the packet for
719  * this protocol.
720  * Also adjusts the available and contained length. */
721 void
722 tvb_set_reported_length(tvbuff_t *tvb, const guint reported_length)
723 {
724         DISSECTOR_ASSERT(tvb && tvb->initialized);
725
726         if (reported_length > tvb->reported_length)
727                 THROW(ReportedBoundsError);
728
729         tvb->reported_length = reported_length;
730         if (reported_length < tvb->length)
731                 tvb->length = reported_length;
732         if (reported_length < tvb->contained_length)
733                 tvb->contained_length = reported_length;
734 }
735
736 guint
737 tvb_offset_from_real_beginning_counter(const tvbuff_t *tvb, const guint counter)
738 {
739         if (tvb->ops->tvb_offset)
740                 return tvb->ops->tvb_offset(tvb, counter);
741
742         DISSECTOR_ASSERT_NOT_REACHED();
743         return 0;
744 }
745
746 guint
747 tvb_offset_from_real_beginning(const tvbuff_t *tvb)
748 {
749         return tvb_offset_from_real_beginning_counter(tvb, 0);
750 }
751
752 static inline const guint8*
753 ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length, int *pexception)
754 {
755         guint abs_offset = 0, abs_length = 0;
756         int   exception;
757
758         exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
759         if (exception) {
760                 if (pexception)
761                         *pexception = exception;
762                 return NULL;
763         }
764
765         /*
766          * Special case: if the caller (e.g. tvb_get_ptr) requested no data,
767          * then it is acceptable to have an empty tvb (!tvb->real_data).
768          */
769         if (length == 0) {
770                 return NULL;
771         }
772
773         /*
774          * We know that all the data is present in the tvbuff, so
775          * no exceptions should be thrown.
776          */
777         if (tvb->real_data)
778                 return tvb->real_data + abs_offset;
779
780         if (tvb->ops->tvb_get_ptr)
781                 return tvb->ops->tvb_get_ptr(tvb, abs_offset, abs_length);
782
783         DISSECTOR_ASSERT_NOT_REACHED();
784         return NULL;
785 }
786
787 static inline const guint8*
788 ensure_contiguous(tvbuff_t *tvb, const gint offset, const gint length)
789 {
790         int           exception = 0;
791         const guint8 *p;
792
793         p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
794         if (p == NULL && length != 0) {
795                 DISSECTOR_ASSERT(exception > 0);
796                 THROW(exception);
797         }
798         return p;
799 }
800
801 static inline const guint8*
802 fast_ensure_contiguous(tvbuff_t *tvb, const gint offset, const guint length)
803 {
804         guint end_offset;
805         guint u_offset;
806
807         DISSECTOR_ASSERT(tvb && tvb->initialized);
808         /* We don't check for overflow in this fast path so we only handle simple types */
809         DISSECTOR_ASSERT(length <= 8);
810
811         if (offset < 0 || !tvb->real_data) {
812                 return ensure_contiguous(tvb, offset, length);
813         }
814
815         u_offset = offset;
816         end_offset = u_offset + length;
817
818         if (G_LIKELY(end_offset <= tvb->length)) {
819                 return tvb->real_data + u_offset;
820         } else if (end_offset <= tvb->contained_length) {
821                 THROW(BoundsError);
822         } else if (end_offset <= tvb->reported_length) {
823                 THROW(ContainedBoundsError);
824         } else if (tvb->flags & TVBUFF_FRAGMENT) {
825                 THROW(FragmentBoundsError);
826         } else {
827                 THROW(ReportedBoundsError);
828         }
829         /* not reached */
830         return NULL;
831 }
832
833
834
835 /************** ACCESSORS **************/
836
837 void *
838 tvb_memcpy(tvbuff_t *tvb, void *target, const gint offset, size_t length)
839 {
840         guint   abs_offset = 0, abs_length = 0;
841
842         DISSECTOR_ASSERT(tvb && tvb->initialized);
843
844         /*
845          * XXX - we should eliminate the "length = -1 means 'to the end
846          * of the tvbuff'" convention, and use other means to achieve
847          * that; this would let us eliminate a bunch of checks for
848          * negative lengths in cases where the protocol has a 32-bit
849          * length field.
850          *
851          * Allowing -1 but throwing an assertion on other negative
852          * lengths is a bit more work with the length being a size_t;
853          * instead, we check for a length <= 2^31-1.
854          */
855         DISSECTOR_ASSERT(length <= 0x7FFFFFFF);
856         check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
857
858         if (tvb->real_data) {
859                 return memcpy(target, tvb->real_data + abs_offset, abs_length);
860         }
861
862         if (tvb->ops->tvb_memcpy)
863                 return tvb->ops->tvb_memcpy(tvb, target, abs_offset, abs_length);
864
865         /*
866          * If the length is 0, there's nothing to do.
867          * (tvb->real_data could be null if it's allocated with
868          * a size of length.)
869          */
870         if (length != 0) {
871                 /*
872                  * XXX, fallback to slower method
873                  */
874                 DISSECTOR_ASSERT_NOT_REACHED();
875         }
876         return NULL;
877 }
878
879
880 /*
881  * XXX - this doesn't treat a length of -1 as an error.
882  * If it did, this could replace some code that calls
883  * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
884  * data to it.
885  *
886  * "composite_get_ptr()" depends on -1 not being
887  * an error; does anything else depend on this routine treating -1 as
888  * meaning "to the end of the buffer"?
889  *
890  * If scope is NULL, memory is allocated with g_malloc() and user must
891  * explicitly free it with g_free().
892  * If scope is not NULL, memory is allocated with the corresponding pool
893  * lifetime.
894  */
895 void *
896 tvb_memdup(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, size_t length)
897 {
898         guint  abs_offset = 0, abs_length = 0;
899         void  *duped;
900
901         DISSECTOR_ASSERT(tvb && tvb->initialized);
902
903         check_offset_length(tvb, offset, (gint) length, &abs_offset, &abs_length);
904
905         duped = wmem_alloc(scope, abs_length);
906         return tvb_memcpy(tvb, duped, abs_offset, abs_length);
907 }
908
909
910
911 const guint8*
912 tvb_get_ptr(tvbuff_t *tvb, const gint offset, const gint length)
913 {
914         return ensure_contiguous(tvb, offset, length);
915 }
916
917 /* ---------------- */
918 guint8
919 tvb_get_guint8(tvbuff_t *tvb, const gint offset)
920 {
921         const guint8 *ptr;
922
923         ptr = fast_ensure_contiguous(tvb, offset, 1);
924         return *ptr;
925 }
926
927 gint8
928 tvb_get_gint8(tvbuff_t *tvb, const gint offset)
929 {
930         const guint8 *ptr;
931
932         ptr = fast_ensure_contiguous(tvb, offset, 1);
933         return *ptr;
934 }
935
936 guint16
937 tvb_get_ntohs(tvbuff_t *tvb, const gint offset)
938 {
939         const guint8 *ptr;
940
941         ptr = fast_ensure_contiguous(tvb, offset, 2);
942         return pntoh16(ptr);
943 }
944
945 gint16
946 tvb_get_ntohis(tvbuff_t *tvb, const gint offset)
947 {
948         const guint8 *ptr;
949
950         ptr = fast_ensure_contiguous(tvb, offset, 2);
951         return pntoh16(ptr);
952 }
953
954 guint32
955 tvb_get_ntoh24(tvbuff_t *tvb, const gint offset)
956 {
957         const guint8 *ptr;
958
959         ptr = fast_ensure_contiguous(tvb, offset, 3);
960         return pntoh24(ptr);
961 }
962
963 gint32
964 tvb_get_ntohi24(tvbuff_t *tvb, const gint offset)
965 {
966         guint32 ret;
967
968         ret = ws_sign_ext32(tvb_get_ntoh24(tvb, offset), 24);
969
970         return (gint32)ret;
971 }
972
973 guint32
974 tvb_get_ntohl(tvbuff_t *tvb, const gint offset)
975 {
976         const guint8 *ptr;
977
978         ptr = fast_ensure_contiguous(tvb, offset, 4);
979         return pntoh32(ptr);
980 }
981
982 gint32
983 tvb_get_ntohil(tvbuff_t *tvb, const gint offset)
984 {
985         const guint8 *ptr;
986
987         ptr = fast_ensure_contiguous(tvb, offset, 4);
988         return pntoh32(ptr);
989 }
990
991 guint64
992 tvb_get_ntoh40(tvbuff_t *tvb, const gint offset)
993 {
994         const guint8 *ptr;
995
996         ptr = fast_ensure_contiguous(tvb, offset, 5);
997         return pntoh40(ptr);
998 }
999
1000 gint64
1001 tvb_get_ntohi40(tvbuff_t *tvb, const gint offset)
1002 {
1003         guint64 ret;
1004
1005         ret = ws_sign_ext64(tvb_get_ntoh40(tvb, offset), 40);
1006
1007         return (gint64)ret;
1008 }
1009
1010 guint64
1011 tvb_get_ntoh48(tvbuff_t *tvb, const gint offset)
1012 {
1013         const guint8 *ptr;
1014
1015         ptr = fast_ensure_contiguous(tvb, offset, 6);
1016         return pntoh48(ptr);
1017 }
1018
1019 gint64
1020 tvb_get_ntohi48(tvbuff_t *tvb, const gint offset)
1021 {
1022         guint64 ret;
1023
1024         ret = ws_sign_ext64(tvb_get_ntoh48(tvb, offset), 48);
1025
1026         return (gint64)ret;
1027 }
1028
1029 guint64
1030 tvb_get_ntoh56(tvbuff_t *tvb, const gint offset)
1031 {
1032         const guint8 *ptr;
1033
1034         ptr = fast_ensure_contiguous(tvb, offset, 7);
1035         return pntoh56(ptr);
1036 }
1037
1038 gint64
1039 tvb_get_ntohi56(tvbuff_t *tvb, const gint offset)
1040 {
1041         guint64 ret;
1042
1043         ret = ws_sign_ext64(tvb_get_ntoh56(tvb, offset), 56);
1044
1045         return (gint64)ret;
1046 }
1047
1048 guint64
1049 tvb_get_ntoh64(tvbuff_t *tvb, const gint offset)
1050 {
1051         const guint8 *ptr;
1052
1053         ptr = fast_ensure_contiguous(tvb, offset, 8);
1054         return pntoh64(ptr);
1055 }
1056
1057 gint64
1058 tvb_get_ntohi64(tvbuff_t *tvb, const gint offset)
1059 {
1060         const guint8 *ptr;
1061
1062         ptr = fast_ensure_contiguous(tvb, offset, 8);
1063         return pntoh64(ptr);
1064 }
1065
1066 guint16
1067 tvb_get_guint16(tvbuff_t *tvb, const gint offset, const guint encoding) {
1068         if (encoding & ENC_LITTLE_ENDIAN) {
1069                 return tvb_get_letohs(tvb, offset);
1070         } else {
1071                 return tvb_get_ntohs(tvb, offset);
1072         }
1073 }
1074
1075 gint16
1076 tvb_get_gint16(tvbuff_t *tvb, const gint offset, const guint encoding) {
1077         if (encoding & ENC_LITTLE_ENDIAN) {
1078                 return tvb_get_letohis(tvb, offset);
1079         } else {
1080                 return tvb_get_ntohis(tvb, offset);
1081         }
1082 }
1083
1084 guint32
1085 tvb_get_guint24(tvbuff_t *tvb, const gint offset, const guint encoding) {
1086         if (encoding & ENC_LITTLE_ENDIAN) {
1087                 return tvb_get_letoh24(tvb, offset);
1088         } else {
1089                 return tvb_get_ntoh24(tvb, offset);
1090         }
1091 }
1092
1093 gint32
1094 tvb_get_gint24(tvbuff_t *tvb, const gint offset, const guint encoding) {
1095         if (encoding & ENC_LITTLE_ENDIAN) {
1096                 return tvb_get_letohi24(tvb, offset);
1097         } else {
1098                 return tvb_get_ntohi24(tvb, offset);
1099         }
1100 }
1101
1102 guint32
1103 tvb_get_guint32(tvbuff_t *tvb, const gint offset, const guint encoding) {
1104         if (encoding & ENC_LITTLE_ENDIAN) {
1105                 return tvb_get_letohl(tvb, offset);
1106         } else {
1107                 return tvb_get_ntohl(tvb, offset);
1108         }
1109 }
1110
1111 gint32
1112 tvb_get_gint32(tvbuff_t *tvb, const gint offset, const guint encoding) {
1113         if (encoding & ENC_LITTLE_ENDIAN) {
1114                 return tvb_get_letohil(tvb, offset);
1115         } else {
1116                 return tvb_get_ntohil(tvb, offset);
1117         }
1118 }
1119
1120 guint64
1121 tvb_get_guint40(tvbuff_t *tvb, const gint offset, const guint encoding) {
1122         if (encoding & ENC_LITTLE_ENDIAN) {
1123                 return tvb_get_letoh40(tvb, offset);
1124         } else {
1125                 return tvb_get_ntoh40(tvb, offset);
1126         }
1127 }
1128
1129 gint64
1130 tvb_get_gint40(tvbuff_t *tvb, const gint offset, const guint encoding) {
1131         if (encoding & ENC_LITTLE_ENDIAN) {
1132                 return tvb_get_letohi40(tvb, offset);
1133         } else {
1134                 return tvb_get_ntohi40(tvb, offset);
1135         }
1136 }
1137
1138 guint64
1139 tvb_get_guint48(tvbuff_t *tvb, const gint offset, const guint encoding) {
1140         if (encoding & ENC_LITTLE_ENDIAN) {
1141                 return tvb_get_letoh48(tvb, offset);
1142         } else {
1143                 return tvb_get_ntoh48(tvb, offset);
1144         }
1145 }
1146
1147 gint64
1148 tvb_get_gint48(tvbuff_t *tvb, const gint offset, const guint encoding) {
1149         if (encoding & ENC_LITTLE_ENDIAN) {
1150                 return tvb_get_letohi48(tvb, offset);
1151         } else {
1152                 return tvb_get_ntohi48(tvb, offset);
1153         }
1154 }
1155
1156 guint64
1157 tvb_get_guint56(tvbuff_t *tvb, const gint offset, const guint encoding) {
1158         if (encoding & ENC_LITTLE_ENDIAN) {
1159                 return tvb_get_letoh56(tvb, offset);
1160         } else {
1161                 return tvb_get_ntoh56(tvb, offset);
1162         }
1163 }
1164
1165 gint64
1166 tvb_get_gint56(tvbuff_t *tvb, const gint offset, const guint encoding) {
1167         if (encoding & ENC_LITTLE_ENDIAN) {
1168                 return tvb_get_letohi56(tvb, offset);
1169         } else {
1170                 return tvb_get_ntohi56(tvb, offset);
1171         }
1172 }
1173
1174 guint64
1175 tvb_get_guint64(tvbuff_t *tvb, const gint offset, const guint encoding) {
1176         if (encoding & ENC_LITTLE_ENDIAN) {
1177                 return tvb_get_letoh64(tvb, offset);
1178         } else {
1179                 return tvb_get_ntoh64(tvb, offset);
1180         }
1181 }
1182
1183 gint64
1184 tvb_get_gint64(tvbuff_t *tvb, const gint offset, const guint encoding) {
1185         if (encoding & ENC_LITTLE_ENDIAN) {
1186                 return tvb_get_letohi64(tvb, offset);
1187         } else {
1188                 return tvb_get_ntohi64(tvb, offset);
1189         }
1190 }
1191
1192 gfloat
1193 tvb_get_ieee_float(tvbuff_t *tvb, const gint offset, const guint encoding) {
1194         if (encoding & ENC_LITTLE_ENDIAN) {
1195                 return tvb_get_letohieee_float(tvb, offset);
1196         } else {
1197                 return tvb_get_ntohieee_float(tvb, offset);
1198         }
1199 }
1200
1201 gdouble
1202 tvb_get_ieee_double(tvbuff_t *tvb, const gint offset, const guint encoding) {
1203         if (encoding & ENC_LITTLE_ENDIAN) {
1204                 return tvb_get_letohieee_double(tvb, offset);
1205         } else {
1206                 return tvb_get_ntohieee_double(tvb, offset);
1207         }
1208 }
1209
1210 /*
1211  * Stuff for IEEE float handling on platforms that don't have IEEE
1212  * format as the native floating-point format.
1213  *
1214  * For now, we treat only the VAX as such a platform.
1215  *
1216  * XXX - other non-IEEE boxes that can run UN*X include some Crays,
1217  * and possibly other machines.  However, I don't know whether there
1218  * are any other machines that could run Wireshark and that don't use
1219  * IEEE format.  As far as I know, all of the main current and past
1220  * commercial microprocessor families on which OSes that support
1221  * Wireshark can run use IEEE format (x86, ARM, 68k, SPARC, MIPS,
1222  * PA-RISC, Alpha, IA-64, and so on), and it appears that the official
1223  * Linux port to System/390 and zArchitecture uses IEEE format floating-
1224  * point rather than IBM hex floating-point (not a huge surprise), so
1225  * I'm not sure that leaves any 32-bit or larger UN*X or Windows boxes,
1226  * other than VAXes, that don't use IEEE format.  If you're not running
1227  * UN*X or Windows, the floating-point format is probably going to be
1228  * the least of your problems in a port.
1229  */
1230
1231 #if defined(vax)
1232
1233 #include <math.h>
1234
1235 /*
1236  * Single-precision.
1237  */
1238 #define IEEE_SP_NUMBER_WIDTH    32      /* bits in number */
1239 #define IEEE_SP_EXP_WIDTH       8       /* bits in exponent */
1240 #define IEEE_SP_MANTISSA_WIDTH  23      /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1241
1242 #define IEEE_SP_SIGN_MASK       0x80000000
1243 #define IEEE_SP_EXPONENT_MASK   0x7F800000
1244 #define IEEE_SP_MANTISSA_MASK   0x007FFFFF
1245 #define IEEE_SP_INFINITY        IEEE_SP_EXPONENT_MASK
1246
1247 #define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1248 #define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1249 #define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1250
1251 static int
1252 ieee_float_is_zero(const guint32 w)
1253 {
1254         return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1255 }
1256
1257 static gfloat
1258 get_ieee_float(const guint32 w)
1259 {
1260         long sign;
1261         long exponent;
1262         long mantissa;
1263
1264         sign = w & IEEE_SP_SIGN_MASK;
1265         exponent = w & IEEE_SP_EXPONENT_MASK;
1266         mantissa = w & IEEE_SP_MANTISSA_MASK;
1267
1268         if (ieee_float_is_zero(w)) {
1269                 /* number is zero, unnormalized, or not-a-number */
1270                 return 0.0;
1271         }
1272 #if 0
1273         /*
1274          * XXX - how to handle this?
1275          */
1276         if (IEEE_SP_INFINITY == exponent) {
1277                 /*
1278                  * number is positive or negative infinity, or a special value
1279                  */
1280                 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1281         }
1282 #endif
1283
1284         exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1285                 IEEE_SP_MANTISSA_WIDTH;
1286         mantissa |= IEEE_SP_IMPLIED_BIT;
1287
1288         if (sign)
1289                 return -mantissa * pow(2, exponent);
1290         else
1291                 return mantissa * pow(2, exponent);
1292 }
1293
1294 /*
1295  * Double-precision.
1296  * We assume that if you don't have IEEE floating-point, you have a
1297  * compiler that understands 64-bit integral quantities.
1298  */
1299 #define IEEE_DP_NUMBER_WIDTH    64      /* bits in number */
1300 #define IEEE_DP_EXP_WIDTH       11      /* bits in exponent */
1301 #define IEEE_DP_MANTISSA_WIDTH  52      /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1302
1303 #define IEEE_DP_SIGN_MASK       G_GINT64_CONSTANT(0x8000000000000000)
1304 #define IEEE_DP_EXPONENT_MASK   G_GINT64_CONSTANT(0x7FF0000000000000)
1305 #define IEEE_DP_MANTISSA_MASK   G_GINT64_CONSTANT(0x000FFFFFFFFFFFFF)
1306 #define IEEE_DP_INFINITY        IEEE_DP_EXPONENT_MASK
1307
1308 #define IEEE_DP_IMPLIED_BIT (G_GINT64_CONSTANT(1) << IEEE_DP_MANTISSA_WIDTH)
1309 #define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1310 #define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1311
1312 static int
1313 ieee_double_is_zero(const guint64 w)
1314 {
1315         return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1316 }
1317
1318 static gdouble
1319 get_ieee_double(const guint64 w)
1320 {
1321         gint64 sign;
1322         gint64 exponent;
1323         gint64 mantissa;
1324
1325         sign = w & IEEE_DP_SIGN_MASK;
1326         exponent = w & IEEE_DP_EXPONENT_MASK;
1327         mantissa = w & IEEE_DP_MANTISSA_MASK;
1328
1329         if (ieee_double_is_zero(w)) {
1330                 /* number is zero, unnormalized, or not-a-number */
1331                 return 0.0;
1332         }
1333 #if 0
1334         /*
1335          * XXX - how to handle this?
1336          */
1337         if (IEEE_DP_INFINITY == exponent) {
1338                 /*
1339                  * number is positive or negative infinity, or a special value
1340                  */
1341                 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1342         }
1343 #endif
1344
1345         exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1346                 IEEE_DP_MANTISSA_WIDTH;
1347         mantissa |= IEEE_DP_IMPLIED_BIT;
1348
1349         if (sign)
1350                 return -mantissa * pow(2, exponent);
1351         else
1352                 return mantissa * pow(2, exponent);
1353 }
1354 #endif
1355
1356 /*
1357  * Fetches an IEEE single-precision floating-point number, in
1358  * big-endian form, and returns a "float".
1359  *
1360  * XXX - should this be "double", in case there are IEEE single-
1361  * precision numbers that won't fit in some platform's native
1362  * "float" format?
1363  */
1364 gfloat
1365 tvb_get_ntohieee_float(tvbuff_t *tvb, const int offset)
1366 {
1367 #if defined(vax)
1368         return get_ieee_float(tvb_get_ntohl(tvb, offset));
1369 #else
1370         union {
1371                 gfloat  f;
1372                 guint32 w;
1373         } ieee_fp_union;
1374
1375         ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1376         return ieee_fp_union.f;
1377 #endif
1378 }
1379
1380 /*
1381  * Fetches an IEEE double-precision floating-point number, in
1382  * big-endian form, and returns a "double".
1383  */
1384 gdouble
1385 tvb_get_ntohieee_double(tvbuff_t *tvb, const int offset)
1386 {
1387 #if defined(vax)
1388         union {
1389                 guint32 w[2];
1390                 guint64 dw;
1391         } ieee_fp_union;
1392 #else
1393         union {
1394                 gdouble d;
1395                 guint32 w[2];
1396         } ieee_fp_union;
1397 #endif
1398
1399 #if G_BYTE_ORDER == G_BIG_ENDIAN
1400         ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1401         ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1402 #else
1403         ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1404         ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1405 #endif
1406 #if defined(vax)
1407         return get_ieee_double(ieee_fp_union.dw);
1408 #else
1409         return ieee_fp_union.d;
1410 #endif
1411 }
1412
1413 guint16
1414 tvb_get_letohs(tvbuff_t *tvb, const gint offset)
1415 {
1416         const guint8 *ptr;
1417
1418         ptr = fast_ensure_contiguous(tvb, offset, 2);
1419         return pletoh16(ptr);
1420 }
1421
1422 gint16
1423 tvb_get_letohis(tvbuff_t *tvb, const gint offset)
1424 {
1425         const guint8 *ptr;
1426
1427         ptr = fast_ensure_contiguous(tvb, offset, 2);
1428         return pletoh16(ptr);
1429 }
1430
1431 guint32
1432 tvb_get_letoh24(tvbuff_t *tvb, const gint offset)
1433 {
1434         const guint8 *ptr;
1435
1436         ptr = fast_ensure_contiguous(tvb, offset, 3);
1437         return pletoh24(ptr);
1438 }
1439
1440 gint32
1441 tvb_get_letohi24(tvbuff_t *tvb, const gint offset)
1442 {
1443         guint32 ret;
1444
1445         ret = ws_sign_ext32(tvb_get_letoh24(tvb, offset), 24);
1446
1447         return (gint32)ret;
1448 }
1449
1450 guint32
1451 tvb_get_letohl(tvbuff_t *tvb, const gint offset)
1452 {
1453         const guint8 *ptr;
1454
1455         ptr = fast_ensure_contiguous(tvb, offset, 4);
1456         return pletoh32(ptr);
1457 }
1458
1459 gint32
1460 tvb_get_letohil(tvbuff_t *tvb, const gint offset)
1461 {
1462         const guint8 *ptr;
1463
1464         ptr = fast_ensure_contiguous(tvb, offset, 4);
1465         return pletoh32(ptr);
1466 }
1467
1468 guint64
1469 tvb_get_letoh40(tvbuff_t *tvb, const gint offset)
1470 {
1471         const guint8 *ptr;
1472
1473         ptr = fast_ensure_contiguous(tvb, offset, 5);
1474         return pletoh40(ptr);
1475 }
1476
1477 gint64
1478 tvb_get_letohi40(tvbuff_t *tvb, const gint offset)
1479 {
1480         guint64 ret;
1481
1482         ret = ws_sign_ext64(tvb_get_letoh40(tvb, offset), 40);
1483
1484         return (gint64)ret;
1485 }
1486
1487 guint64
1488 tvb_get_letoh48(tvbuff_t *tvb, const gint offset)
1489 {
1490         const guint8 *ptr;
1491
1492         ptr = fast_ensure_contiguous(tvb, offset, 6);
1493         return pletoh48(ptr);
1494 }
1495
1496 gint64
1497 tvb_get_letohi48(tvbuff_t *tvb, const gint offset)
1498 {
1499         guint64 ret;
1500
1501         ret = ws_sign_ext64(tvb_get_letoh48(tvb, offset), 48);
1502
1503         return (gint64)ret;
1504 }
1505
1506 guint64
1507 tvb_get_letoh56(tvbuff_t *tvb, const gint offset)
1508 {
1509         const guint8 *ptr;
1510
1511         ptr = fast_ensure_contiguous(tvb, offset, 7);
1512         return pletoh56(ptr);
1513 }
1514
1515 gint64
1516 tvb_get_letohi56(tvbuff_t *tvb, const gint offset)
1517 {
1518         guint64 ret;
1519
1520         ret = ws_sign_ext64(tvb_get_letoh56(tvb, offset), 56);
1521
1522         return (gint64)ret;
1523 }
1524
1525 guint64
1526 tvb_get_letoh64(tvbuff_t *tvb, const gint offset)
1527 {
1528         const guint8 *ptr;
1529
1530         ptr = fast_ensure_contiguous(tvb, offset, 8);
1531         return pletoh64(ptr);
1532 }
1533
1534 gint64
1535 tvb_get_letohi64(tvbuff_t *tvb, const gint offset)
1536 {
1537         const guint8 *ptr;
1538
1539         ptr = fast_ensure_contiguous(tvb, offset, 8);
1540         return pletoh64(ptr);
1541 }
1542
1543 /*
1544  * Fetches an IEEE single-precision floating-point number, in
1545  * little-endian form, and returns a "float".
1546  *
1547  * XXX - should this be "double", in case there are IEEE single-
1548  * precision numbers that won't fit in some platform's native
1549  * "float" format?
1550  */
1551 gfloat
1552 tvb_get_letohieee_float(tvbuff_t *tvb, const int offset)
1553 {
1554 #if defined(vax)
1555         return get_ieee_float(tvb_get_letohl(tvb, offset));
1556 #else
1557         union {
1558                 gfloat f;
1559                 guint32 w;
1560         } ieee_fp_union;
1561
1562         ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1563         return ieee_fp_union.f;
1564 #endif
1565 }
1566
1567 /*
1568  * Fetches an IEEE double-precision floating-point number, in
1569  * little-endian form, and returns a "double".
1570  */
1571 gdouble
1572 tvb_get_letohieee_double(tvbuff_t *tvb, const int offset)
1573 {
1574 #if defined(vax)
1575         union {
1576                 guint32 w[2];
1577                 guint64 dw;
1578         } ieee_fp_union;
1579 #else
1580         union {
1581                 gdouble d;
1582                 guint32 w[2];
1583         } ieee_fp_union;
1584 #endif
1585
1586 #if G_BYTE_ORDER == G_BIG_ENDIAN
1587         ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1588         ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1589 #else
1590         ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1591         ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1592 #endif
1593 #if defined(vax)
1594         return get_ieee_double(ieee_fp_union.dw);
1595 #else
1596         return ieee_fp_union.d;
1597 #endif
1598 }
1599
1600 static inline void
1601 validate_single_byte_ascii_encoding(const guint encoding)
1602 {
1603         const guint enc = encoding & ~ENC_STR_MASK;
1604
1605         switch (enc) {
1606             case ENC_UTF_16:
1607             case ENC_UCS_2:
1608             case ENC_UCS_4:
1609             case ENC_3GPP_TS_23_038_7BITS:
1610             case ENC_EBCDIC:
1611                 REPORT_DISSECTOR_BUG("Invalid string encoding type passed to tvb_get_string_XXX");
1612                 break;
1613             default:
1614                 break;
1615         }
1616         /* make sure something valid was set */
1617         if (enc == 0)
1618             REPORT_DISSECTOR_BUG("No string encoding type passed to tvb_get_string_XXX");
1619 }
1620
1621 GByteArray*
1622 tvb_get_string_bytes(tvbuff_t *tvb, const gint offset, const gint length,
1623                      const guint encoding, GByteArray *bytes, gint *endoff)
1624 {
1625         const gchar *ptr    = (gchar*) tvb_get_raw_string(wmem_packet_scope(), tvb, offset, length);
1626         const gchar *begin  = ptr;
1627         const gchar *end    = NULL;
1628         GByteArray  *retval = NULL;
1629
1630         errno = EDOM;
1631
1632         validate_single_byte_ascii_encoding(encoding);
1633
1634         if (endoff) *endoff = 0;
1635
1636         while (*begin == ' ') begin++;
1637
1638         if (*begin && bytes) {
1639                 if (hex_str_to_bytes_encoding(begin, bytes, &end, encoding, FALSE)) {
1640                         if (bytes->len > 0) {
1641                                 if (endoff) *endoff = offset + (gint)(end - ptr);
1642                                 errno = 0;
1643                                 retval = bytes;
1644                         }
1645                 }
1646         }
1647
1648         return retval;
1649 }
1650
1651 /* support hex-encoded time values? */
1652 nstime_t*
1653 tvb_get_string_time(tvbuff_t *tvb, const gint offset, const gint length,
1654                     const guint encoding, nstime_t *ns, gint *endoff)
1655 {
1656         const gchar *begin     = (gchar*) tvb_get_raw_string(wmem_packet_scope(), tvb, offset, length);
1657         const gchar *ptr       = begin;
1658         const gchar *end       = NULL;
1659         struct tm    tm;
1660         nstime_t*    retval    = NULL;
1661         char         sign      = '+';
1662         int          off_hr    = 0;
1663         int          off_min   = 0;
1664         int          num_chars = 0;
1665         gboolean     matched   = FALSE;
1666
1667         errno = EDOM;
1668
1669         validate_single_byte_ascii_encoding(encoding);
1670
1671         DISSECTOR_ASSERT(ns);
1672
1673         memset(&tm, 0, sizeof(tm));
1674         tm.tm_isdst = -1;
1675         ns->secs    = 0;
1676         ns->nsecs   = 0;
1677
1678         while (*ptr == ' ') ptr++;
1679
1680         if (*ptr) {
1681                 /* note: sscanf is known to be inconsistent across platforms with respect
1682                    to whether a %n is counted as a return value or not, so we have to use
1683                    '>=' a lot */
1684                 if ((encoding & ENC_ISO_8601_DATE_TIME) == ENC_ISO_8601_DATE_TIME) {
1685                         /* TODO: using sscanf this many times is probably slow; might want
1686                            to parse it by hand in the future */
1687                         /* 2014-04-07T05:41:56+00:00 */
1688                         if (sscanf(ptr, "%d-%d-%d%*c%d:%d:%d%c%d:%d%n",
1689                             &tm.tm_year,
1690                             &tm.tm_mon,
1691                             &tm.tm_mday,
1692                             &tm.tm_hour,
1693                             &tm.tm_min,
1694                             &tm.tm_sec,
1695                             &sign,
1696                             &off_hr,
1697                             &off_min,
1698                             &num_chars) >= 9)
1699                         {
1700                                 matched = TRUE;
1701                         }
1702                         /* no seconds is ok */
1703                         else if (sscanf(ptr, "%d-%d-%d%*c%d:%d%c%d:%d%n",
1704                             &tm.tm_year,
1705                             &tm.tm_mon,
1706                             &tm.tm_mday,
1707                             &tm.tm_hour,
1708                             &tm.tm_min,
1709                             &sign,
1710                             &off_hr,
1711                             &off_min,
1712                             &num_chars) >= 8)
1713                         {
1714                                 matched = TRUE;
1715                         }
1716                         /* 2007-04-05T14:30:56Z */
1717                         else if (sscanf(ptr, "%d-%d-%d%*c%d:%d:%dZ%n",
1718                             &tm.tm_year,
1719                             &tm.tm_mon,
1720                             &tm.tm_mday,
1721                             &tm.tm_hour,
1722                             &tm.tm_min,
1723                             &tm.tm_sec,
1724                             &num_chars) >= 6)
1725                         {
1726                                 matched = TRUE;
1727                                 off_hr = 0;
1728                                 off_min = 0;
1729                         }
1730                         /* 2007-04-05T14:30Z no seconds is ok */
1731                         else if (sscanf(ptr, "%d-%d-%d%*c%d:%dZ%n",
1732                             &tm.tm_year,
1733                             &tm.tm_mon,
1734                             &tm.tm_mday,
1735                             &tm.tm_hour,
1736                             &tm.tm_min,
1737                             &num_chars) >= 5)
1738                         {
1739                                 matched = TRUE;
1740                                 off_hr = 0;
1741                                 off_min = 0;
1742                         }
1743
1744                         if (matched) {
1745                                 errno = 0;
1746                                 end = ptr + num_chars;
1747                                 tm.tm_mon--;
1748                                 if (tm.tm_year > 1900) tm.tm_year -= 1900;
1749                                 if (sign == '-') off_hr = -off_hr;
1750                         }
1751                 }
1752                 else if (encoding & ENC_ISO_8601_DATE) {
1753                         /* 2014-04-07 */
1754                         if (sscanf(ptr, "%d-%d-%d%n",
1755                             &tm.tm_year,
1756                             &tm.tm_mon,
1757                             &tm.tm_mday,
1758                             &num_chars) >= 3)
1759                         {
1760                                 errno = 0;
1761                                 end = ptr + num_chars;
1762                                 tm.tm_mon--;
1763                                 if (tm.tm_year > 1900) tm.tm_year -= 1900;
1764                         }
1765                 }
1766                 else if (encoding & ENC_ISO_8601_TIME) {
1767                         /* 2014-04-07 */
1768                         if (sscanf(ptr, "%d:%d:%d%n",
1769                             &tm.tm_hour,
1770                             &tm.tm_min,
1771                             &tm.tm_sec,
1772                             &num_chars) >= 2)
1773                         {
1774                                 /* what should we do about day/month/year? */
1775                                 /* setting it to "now" for now */
1776                                 time_t time_now = time(NULL);
1777                                 struct tm *tm_now = gmtime(&time_now);
1778                                 if (tm_now != NULL) {
1779                                         tm.tm_year = tm_now->tm_year;
1780                                         tm.tm_mon  = tm_now->tm_mon;
1781                                         tm.tm_mday = tm_now->tm_mday;
1782                                 } else {
1783                                         /* The second before the Epoch */
1784                                         tm.tm_year = 69;
1785                                         tm.tm_mon = 12;
1786                                         tm.tm_mday = 31;
1787                                 }
1788                                 end = ptr + num_chars;
1789                                 errno = 0;
1790
1791                         }
1792                 }
1793                 else if (encoding & ENC_RFC_822 || encoding & ENC_RFC_1123) {
1794                         if (encoding & ENC_RFC_822) {
1795                                 /* this will unfortunately match ENC_RFC_1123 style
1796                                    strings too, partially - probably need to do this the long way */
1797                                 end = strptime(ptr, "%a, %d %b %y %H:%M:%S", &tm);
1798                                 if (!end) end = strptime(ptr, "%a, %d %b %y %H:%M", &tm);
1799                                 if (!end) end = strptime(ptr, "%d %b %y %H:%M:%S", &tm);
1800                                 if (!end) end = strptime(ptr, "%d %b %y %H:%M", &tm);
1801                         }
1802                         else if (encoding & ENC_RFC_1123) {
1803                                 end = strptime(ptr, "%a, %d %b %Y %H:%M:%S", &tm);
1804                                 if (!end) end = strptime(ptr, "%a, %d %b %Y %H:%M", &tm);
1805                                 if (!end) end = strptime(ptr, "%d %b %Y %H:%M:%S", &tm);
1806                                 if (!end) end = strptime(ptr, "%d %b %Y %H:%M", &tm);
1807                         }
1808                         if (end) {
1809                                 errno = 0;
1810                                 if (*end == ' ') end++;
1811                                 if (g_ascii_strncasecmp(end, "UT", 2) == 0)
1812                                 {
1813                                         end += 2;
1814                                 }
1815                                 else if (g_ascii_strncasecmp(end, "GMT", 3) == 0)
1816                                 {
1817                                         end += 3;
1818                                 }
1819                                 else if (sscanf(end, "%c%2d%2d%n",
1820                                     &sign,
1821                                     &off_hr,
1822                                     &off_min,
1823                                     &num_chars) < 3)
1824                                 {
1825                                         errno = ERANGE;
1826                                 }
1827                                 if (sign == '-') off_hr = -off_hr;
1828                         }
1829                 }
1830         }
1831
1832         if (errno == 0) {
1833                 ns->secs = mktime_utc (&tm);
1834                 if (off_hr > 0)
1835                         ns->secs += (off_hr * 3600) + (off_min * 60);
1836                 else if (off_hr < 0)
1837                         ns->secs -= ((-off_hr) * 3600) + (off_min * 60);
1838                 retval = ns;
1839                 if (endoff)
1840                     *endoff = (gint)(offset + (end - begin));
1841         }
1842
1843         return retval;
1844 }
1845
1846 /* Fetch an IPv4 address, in network byte order.
1847  * We do *not* convert them to host byte order; we leave them in
1848  * network byte order. */
1849 guint32
1850 tvb_get_ipv4(tvbuff_t *tvb, const gint offset)
1851 {
1852         const guint8 *ptr;
1853         guint32       addr;
1854
1855         ptr = fast_ensure_contiguous(tvb, offset, sizeof(guint32));
1856         memcpy(&addr, ptr, sizeof addr);
1857         return addr;
1858 }
1859
1860 /* Fetch an IPv6 address. */
1861 void
1862 tvb_get_ipv6(tvbuff_t *tvb, const gint offset, ws_in6_addr *addr)
1863 {
1864         const guint8 *ptr;
1865
1866         ptr = ensure_contiguous(tvb, offset, sizeof(*addr));
1867         memcpy(addr, ptr, sizeof *addr);
1868 }
1869
1870 /* Fetch a GUID. */
1871 void
1872 tvb_get_ntohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid)
1873 {
1874         const guint8 *ptr = ensure_contiguous(tvb, offset, GUID_LEN);
1875
1876         guid->data1 = pntoh32(ptr + 0);
1877         guid->data2 = pntoh16(ptr + 4);
1878         guid->data3 = pntoh16(ptr + 6);
1879         memcpy(guid->data4, ptr + 8, sizeof guid->data4);
1880 }
1881
1882 void
1883 tvb_get_letohguid(tvbuff_t *tvb, const gint offset, e_guid_t *guid)
1884 {
1885         const guint8 *ptr = ensure_contiguous(tvb, offset, GUID_LEN);
1886
1887         guid->data1 = pletoh32(ptr + 0);
1888         guid->data2 = pletoh16(ptr + 4);
1889         guid->data3 = pletoh16(ptr + 6);
1890         memcpy(guid->data4, ptr + 8, sizeof guid->data4);
1891 }
1892
1893 /*
1894  * NOTE: to support code written when proto_tree_add_item() took a
1895  * gboolean as its last argument, with FALSE meaning "big-endian"
1896  * and TRUE meaning "little-endian", we treat any non-zero value of
1897  * "encoding" as meaning "little-endian".
1898  */
1899 void
1900 tvb_get_guid(tvbuff_t *tvb, const gint offset, e_guid_t *guid, const guint encoding)
1901 {
1902         if (encoding) {
1903                 tvb_get_letohguid(tvb, offset, guid);
1904         } else {
1905                 tvb_get_ntohguid(tvb, offset, guid);
1906         }
1907 }
1908
1909 static const guint8 bit_mask8[] = {
1910         0x00,
1911         0x01,
1912         0x03,
1913         0x07,
1914         0x0f,
1915         0x1f,
1916         0x3f,
1917         0x7f,
1918         0xff
1919 };
1920
1921 /* Get 1 - 8 bits */
1922 guint8
1923 tvb_get_bits8(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits)
1924 {
1925         return (guint8)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1926 }
1927
1928 /* Get 9 - 16 bits */
1929 guint16
1930 tvb_get_bits16(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits,const guint encoding _U_)
1931 {
1932         /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1933         return (guint16)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1934 }
1935
1936 /* Get 1 - 32 bits */
1937 guint32
1938 tvb_get_bits32(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits, const guint encoding _U_)
1939 {
1940         /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1941         return (guint32)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
1942 }
1943
1944 /* Get 1 - 64 bits */
1945 guint64
1946 tvb_get_bits64(tvbuff_t *tvb, guint bit_offset, const gint no_of_bits, const guint encoding _U_)
1947 {
1948         /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
1949         return _tvb_get_bits64(tvb, bit_offset, no_of_bits);
1950 }
1951 /*
1952  * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
1953  * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
1954  * Offset should be given in bits from the start of the tvb.
1955  * The function tolerates requests for more than 64 bits, but will only return the least significant 64 bits.
1956  */
1957 static guint64
1958 _tvb_get_bits64(tvbuff_t *tvb, guint bit_offset, const gint total_no_of_bits)
1959 {
1960         guint64 value;
1961         guint   octet_offset = bit_offset >> 3;
1962         guint8  required_bits_in_first_octet = 8 - (bit_offset % 8);
1963
1964         if(required_bits_in_first_octet > total_no_of_bits)
1965         {
1966                 /* the required bits don't extend to the end of the first octet */
1967                 guint8 right_shift = required_bits_in_first_octet - total_no_of_bits;
1968                 value = (tvb_get_guint8(tvb, octet_offset) >> right_shift) & bit_mask8[total_no_of_bits % 8];
1969         }
1970         else
1971         {
1972                 guint8 remaining_bit_length = total_no_of_bits;
1973
1974                 /* get the bits up to the first octet boundary */
1975                 value = 0;
1976                 required_bits_in_first_octet %= 8;
1977                 if(required_bits_in_first_octet != 0)
1978                 {
1979                         value = tvb_get_guint8(tvb, octet_offset) & bit_mask8[required_bits_in_first_octet];
1980                         remaining_bit_length -= required_bits_in_first_octet;
1981                         octet_offset ++;
1982                 }
1983                 /* take the biggest words, shorts or octets that we can */
1984                 while (remaining_bit_length > 7)
1985                 {
1986                         switch (remaining_bit_length >> 4)
1987                         {
1988                         case 0:
1989                                 /* 8 - 15 bits. (note that 0 - 7 would have dropped out of the while() loop) */
1990                                 value <<= 8;
1991                                 value += tvb_get_guint8(tvb, octet_offset);
1992                                 remaining_bit_length -= 8;
1993                                 octet_offset ++;
1994                                 break;
1995
1996                         case 1:
1997                                 /* 16 - 31 bits */
1998                                 value <<= 16;
1999                                 value += tvb_get_ntohs(tvb, octet_offset);
2000                                 remaining_bit_length -= 16;
2001                                 octet_offset += 2;
2002                                 break;
2003
2004                         case 2:
2005                         case 3:
2006                                 /* 32 - 63 bits */
2007                                 value <<= 32;
2008                                 value += tvb_get_ntohl(tvb, octet_offset);
2009                                 remaining_bit_length -= 32;
2010                                 octet_offset += 4;
2011                                 break;
2012
2013                         default:
2014                                 /* 64 bits (or more???) */
2015                                 value = tvb_get_ntoh64(tvb, octet_offset);
2016                                 remaining_bit_length -= 64;
2017                                 octet_offset += 8;
2018                                 break;
2019                         }
2020                 }
2021                 /* get bits from any partial octet at the tail */
2022                 if(remaining_bit_length)
2023                 {
2024                         value <<= remaining_bit_length;
2025                         value += (tvb_get_guint8(tvb, octet_offset) >> (8 - remaining_bit_length));
2026                 }
2027         }
2028         return value;
2029 }
2030 /* Get 1 - 32 bits (should be deprecated as same as tvb_get_bits32??) */
2031 guint32
2032 tvb_get_bits(tvbuff_t *tvb, const guint bit_offset, const gint no_of_bits, const guint encoding _U_)
2033 {
2034         /* note that encoding has no meaning here, as the tvb is considered to contain an octet array */
2035         return (guint32)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
2036 }
2037
2038 static gint
2039 tvb_find_guint8_generic(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
2040 {
2041         const guint8 *ptr;
2042         const guint8 *result;
2043
2044         ptr = ensure_contiguous(tvb, abs_offset, limit); /* tvb_get_ptr() */
2045
2046         result = (const guint8 *) memchr(ptr, needle, limit);
2047         if (!result)
2048                 return -1;
2049
2050         return (gint) ((result - ptr) + abs_offset);
2051 }
2052
2053 /* Find first occurrence of needle in tvbuff, starting at offset. Searches
2054  * at most maxlength number of bytes; if maxlength is -1, searches to
2055  * end of tvbuff.
2056  * Returns the offset of the found needle, or -1 if not found.
2057  * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
2058  * in that case, -1 will be returned if the boundary is reached before
2059  * finding needle. */
2060 gint
2061 tvb_find_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 needle)
2062 {
2063         const guint8 *result;
2064         guint         abs_offset = 0;
2065         guint         limit = 0;
2066         int           exception;
2067
2068         DISSECTOR_ASSERT(tvb && tvb->initialized);
2069
2070         exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &limit);
2071         if (exception)
2072                 THROW(exception);
2073
2074         /* Only search to end of tvbuff, w/o throwing exception. */
2075         if (maxlength >= 0 && limit > (guint) maxlength) {
2076                 /* Maximum length doesn't go past end of tvbuff; search
2077                    to that value. */
2078                 limit = (guint) maxlength;
2079         }
2080
2081         /* If we have real data, perform our search now. */
2082         if (tvb->real_data) {
2083                 result = (const guint8 *)memchr(tvb->real_data + abs_offset, needle, limit);
2084                 if (result == NULL) {
2085                         return -1;
2086                 }
2087                 else {
2088                         return (gint) (result - tvb->real_data);
2089                 }
2090         }
2091
2092         if (tvb->ops->tvb_find_guint8)
2093                 return tvb->ops->tvb_find_guint8(tvb, abs_offset, limit, needle);
2094
2095         return tvb_find_guint8_generic(tvb, offset, limit, needle);
2096 }
2097
2098 /* Same as tvb_find_guint8() with 16bit needle. */
2099 gint
2100 tvb_find_guint16(tvbuff_t *tvb, const gint offset, const gint maxlength,
2101                  const guint16 needle)
2102 {
2103         const guint8 needle1 = ((needle & 0xFF00) >> 8);
2104         const guint8 needle2 = ((needle & 0x00FF) >> 0);
2105         gint searched_bytes = 0;
2106         gint pos = offset;
2107
2108         do {
2109                 gint offset1 =
2110                         tvb_find_guint8(tvb, pos, maxlength - searched_bytes, needle1);
2111                 gint offset2 = -1;
2112
2113                 if (offset1 == -1) {
2114                         return -1;
2115                 }
2116
2117                 searched_bytes = offset - pos + 1;
2118
2119                 if ((maxlength != -1) && (searched_bytes >= maxlength)) {
2120                         return -1;
2121                 }
2122
2123                 offset2 = tvb_find_guint8(tvb, offset1 + 1, 1, needle2);
2124
2125                 searched_bytes += 1;
2126
2127                 if (offset2 != -1) {
2128                         if ((maxlength != -1) && (searched_bytes > maxlength)) {
2129                                 return -1;
2130                         }
2131                         return offset1;
2132                 }
2133
2134                 pos = offset1 + 1;
2135         } while (searched_bytes < maxlength);
2136
2137         return -1;
2138 }
2139
2140 static inline gint
2141 tvb_ws_mempbrk_guint8_generic(tvbuff_t *tvb, guint abs_offset, guint limit, const ws_mempbrk_pattern* pattern, guchar *found_needle)
2142 {
2143         const guint8 *ptr;
2144         const guint8 *result;
2145
2146         ptr = ensure_contiguous(tvb, abs_offset, limit); /* tvb_get_ptr */
2147
2148         result = ws_mempbrk_exec(ptr, limit, pattern, found_needle);
2149         if (!result)
2150                 return -1;
2151
2152         return (gint) ((result - ptr) + abs_offset);
2153 }
2154
2155
2156 /* Find first occurrence of any of the pattern chars in tvbuff, starting at offset.
2157  * Searches at most maxlength number of bytes; if maxlength is -1, searches
2158  * to end of tvbuff.
2159  * Returns the offset of the found needle, or -1 if not found.
2160  * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
2161  * in that case, -1 will be returned if the boundary is reached before
2162  * finding needle. */
2163 gint
2164 tvb_ws_mempbrk_pattern_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength,
2165                         const ws_mempbrk_pattern* pattern, guchar *found_needle)
2166 {
2167         const guint8 *result;
2168         guint         abs_offset = 0;
2169         guint         limit = 0;
2170         int           exception;
2171
2172         DISSECTOR_ASSERT(tvb && tvb->initialized);
2173
2174         exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &limit);
2175         if (exception)
2176                 THROW(exception);
2177
2178         /* Only search to end of tvbuff, w/o throwing exception. */
2179         if (limit > (guint) maxlength) {
2180                 /* Maximum length doesn't go past end of tvbuff; search
2181                    to that value. */
2182                 limit = maxlength;
2183         }
2184
2185         /* If we have real data, perform our search now. */
2186         if (tvb->real_data) {
2187                 result = ws_mempbrk_exec(tvb->real_data + abs_offset, limit, pattern, found_needle);
2188                 if (result == NULL) {
2189                         return -1;
2190                 }
2191                 else {
2192                         return (gint) (result - tvb->real_data);
2193                 }
2194         }
2195
2196         if (tvb->ops->tvb_ws_mempbrk_pattern_guint8)
2197                 return tvb->ops->tvb_ws_mempbrk_pattern_guint8(tvb, abs_offset, limit, pattern, found_needle);
2198
2199         return tvb_ws_mempbrk_guint8_generic(tvb, abs_offset, limit, pattern, found_needle);
2200 }
2201
2202 /* Find size of stringz (NUL-terminated string) by looking for terminating
2203  * NUL.  The size of the string includes the terminating NUL.
2204  *
2205  * If the NUL isn't found, it throws the appropriate exception.
2206  */
2207 guint
2208 tvb_strsize(tvbuff_t *tvb, const gint offset)
2209 {
2210         guint abs_offset = 0, junk_length;
2211         gint  nul_offset;
2212
2213         DISSECTOR_ASSERT(tvb && tvb->initialized);
2214
2215         check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
2216         nul_offset = tvb_find_guint8(tvb, abs_offset, -1, 0);
2217         if (nul_offset == -1) {
2218                 /*
2219                  * OK, we hit the end of the tvbuff, so we should throw
2220                  * an exception.
2221                  */
2222                 if (tvb->length < tvb->contained_length) {
2223                         THROW(BoundsError);
2224                 } else if (tvb->length < tvb->reported_length) {
2225                         THROW(ContainedBoundsError);
2226                 } else if (tvb->flags & TVBUFF_FRAGMENT) {
2227                         THROW(FragmentBoundsError);
2228                 } else {
2229                         THROW(ReportedBoundsError);
2230                 }
2231         }
2232         return (nul_offset - abs_offset) + 1;
2233 }
2234
2235 /* UTF-16/UCS-2 version of tvb_strsize */
2236 /* Returns number of bytes including the (two-bytes) null terminator */
2237 guint
2238 tvb_unicode_strsize(tvbuff_t *tvb, const gint offset)
2239 {
2240         guint     i = 0;
2241         gunichar2 uchar;
2242
2243         DISSECTOR_ASSERT(tvb && tvb->initialized);
2244
2245         do {
2246                 /* Endianness doesn't matter when looking for null */
2247                 uchar = tvb_get_ntohs(tvb, offset + i);
2248                 i += 2;
2249         } while(uchar != 0);
2250
2251         return i;
2252 }
2253
2254 /* Find length of string by looking for end of string ('\0'), up to
2255  * 'maxlength' characters'; if 'maxlength' is -1, searches to end
2256  * of tvbuff.
2257  * Returns -1 if 'maxlength' reached before finding EOS. */
2258 gint
2259 tvb_strnlen(tvbuff_t *tvb, const gint offset, const guint maxlength)
2260 {
2261         gint  result_offset;
2262         guint abs_offset = 0, junk_length;
2263
2264         DISSECTOR_ASSERT(tvb && tvb->initialized);
2265
2266         check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
2267
2268         result_offset = tvb_find_guint8(tvb, abs_offset, maxlength, 0);
2269
2270         if (result_offset == -1) {
2271                 return -1;
2272         }
2273         else {
2274                 return result_offset - abs_offset;
2275         }
2276 }
2277
2278 /*
2279  * Implement strneql etc
2280  */
2281
2282 /*
2283  * Call strncmp after checking if enough chars left, returning 0 if
2284  * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2285  */
2286 gint
2287 tvb_strneql(tvbuff_t *tvb, const gint offset, const gchar *str, const size_t size)
2288 {
2289         const guint8 *ptr;
2290
2291         ptr = ensure_contiguous_no_exception(tvb, offset, (gint)size, NULL);
2292
2293         if (ptr) {
2294                 int cmp = strncmp((const char *)ptr, str, size);
2295
2296                 /*
2297                  * Return 0 if equal, -1 otherwise.
2298                  */
2299                 return (cmp == 0 ? 0 : -1);
2300         } else {
2301                 /*
2302                  * Not enough characters in the tvbuff to match the
2303                  * string.
2304                  */
2305                 return -1;
2306         }
2307 }
2308
2309 /*
2310  * Call g_ascii_strncasecmp after checking if enough chars left, returning
2311  * 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2312  */
2313 gint
2314 tvb_strncaseeql(tvbuff_t *tvb, const gint offset, const gchar *str, const size_t size)
2315 {
2316         const guint8 *ptr;
2317
2318         ptr = ensure_contiguous_no_exception(tvb, offset, (gint)size, NULL);
2319
2320         if (ptr) {
2321                 int cmp = g_ascii_strncasecmp((const char *)ptr, str, size);
2322
2323                 /*
2324                  * Return 0 if equal, -1 otherwise.
2325                  */
2326                 return (cmp == 0 ? 0 : -1);
2327         } else {
2328                 /*
2329                  * Not enough characters in the tvbuff to match the
2330                  * string.
2331                  */
2332                 return -1;
2333         }
2334 }
2335
2336 /*
2337  * Check that the tvbuff contains at least size bytes, starting at
2338  * offset, and that those bytes are equal to str. Return 0 for success
2339  * and -1 for error. This function does not throw an exception.
2340  */
2341 gint
2342 tvb_memeql(tvbuff_t *tvb, const gint offset, const guint8 *str, size_t size)
2343 {
2344         const guint8 *ptr;
2345
2346         ptr = ensure_contiguous_no_exception(tvb, offset, (gint) size, NULL);
2347
2348         if (ptr) {
2349                 int cmp = memcmp(ptr, str, size);
2350
2351                 /*
2352                  * Return 0 if equal, -1 otherwise.
2353                  */
2354                 return (cmp == 0 ? 0 : -1);
2355         } else {
2356                 /*
2357                  * Not enough characters in the tvbuff to match the
2358                  * string.
2359                  */
2360                 return -1;
2361         }
2362 }
2363
2364 /**
2365  * Format the data in the tvb from offset for size.  Returned string is
2366  * wmem packet_scoped so call must be in that scope.
2367  */
2368 gchar *
2369 tvb_format_text(tvbuff_t *tvb, const gint offset, const gint size)
2370 {
2371         const guint8 *ptr;
2372         gint          len;
2373
2374         len = (size > 0) ? size : 0;
2375
2376         ptr = ensure_contiguous(tvb, offset, size);
2377         return format_text(wmem_packet_scope(), ptr, len);
2378 }
2379
2380 /*
2381  * Format the data in the tvb from offset for length ...
2382  */
2383 gchar *
2384 tvb_format_text_wsp(wmem_allocator_t* allocator, tvbuff_t *tvb, const gint offset, const gint size)
2385 {
2386         const guint8 *ptr;
2387         gint          len;
2388
2389         len = (size > 0) ? size : 0;
2390
2391         ptr = ensure_contiguous(tvb, offset, size);
2392         return format_text_wsp(allocator, ptr, len);
2393 }
2394
2395 /**
2396  * Like "tvb_format_text()", but for null-padded strings; don't show
2397  * the null padding characters as "\000".  Returned string is wmem packet_scoped
2398  * so call must be in that scope.
2399  */
2400 gchar *
2401 tvb_format_stringzpad(tvbuff_t *tvb, const gint offset, const gint size)
2402 {
2403         const guint8 *ptr, *p;
2404         gint          len;
2405         gint          stringlen;
2406
2407         len = (size > 0) ? size : 0;
2408
2409         ptr = ensure_contiguous(tvb, offset, size);
2410         for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2411                 ;
2412         return format_text(wmem_packet_scope(), ptr, stringlen);
2413 }
2414
2415 /*
2416  * Like "tvb_format_text_wsp()", but for null-padded strings; don't show
2417  * the null padding characters as "\000".
2418  */
2419 gchar *
2420 tvb_format_stringzpad_wsp(wmem_allocator_t* allocator, tvbuff_t *tvb, const gint offset, const gint size)
2421 {
2422         const guint8 *ptr, *p;
2423         gint          len;
2424         gint          stringlen;
2425
2426         len = (size > 0) ? size : 0;
2427
2428         ptr = ensure_contiguous(tvb, offset, size);
2429         for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2430                 ;
2431         return format_text_wsp(allocator, ptr, stringlen);
2432 }
2433
2434 /* Unicode REPLACEMENT CHARACTER */
2435 #define UNREPL 0x00FFFD
2436
2437 /*
2438  * All string functions below take a scope as an argument.
2439  *
2440  *
2441  * If scope is NULL, memory is allocated with g_malloc() and user must
2442  * explicitly free it with g_free().
2443  * If scope is not NULL, memory is allocated with the corresponding pool
2444  * lifetime.
2445  *
2446  * All functions throw an exception if the tvbuff ends before the string
2447  * does.
2448  */
2449
2450 /*
2451  * Given a wmem scope, tvbuff, an offset, and a length, treat the string
2452  * of bytes referred to by the tvbuff, offset, and length as an ASCII string,
2453  * with all bytes with the high-order bit set being invalid, and return a
2454  * pointer to a UTF-8 string, allocated using the wmem scope.
2455  *
2456  * Octets with the highest bit set will be converted to the Unicode
2457  * REPLACEMENT CHARACTER.
2458  */
2459 static guint8 *
2460 tvb_get_ascii_string(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length)
2461 {
2462         const guint8  *ptr;
2463
2464         ptr = ensure_contiguous(tvb, offset, length);
2465         return get_ascii_string(scope, ptr, length);
2466 }
2467
2468 /*
2469  * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2470  * of bytes referred to by the tvbuff, the offset. and the length as a UTF-8
2471  * string, and return a pointer to that string, allocated using the wmem scope.
2472  *
2473  * XXX - should map invalid UTF-8 sequences to UNREPL.
2474  */
2475 static guint8 *
2476 tvb_get_utf_8_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint length)
2477 {
2478         guint8 *strbuf;
2479
2480         tvb_ensure_bytes_exist(tvb, offset, length); /* make sure length = -1 fails */
2481         strbuf = (guint8 *)wmem_alloc(scope, length + 1);
2482         tvb_memcpy(tvb, strbuf, offset, length);
2483         strbuf[length] = '\0';
2484         return strbuf;
2485 }
2486
2487 /*
2488  * Given a wmem scope, tvbuff, an offset, and a length, treat the string
2489  * of bytes referred to by the tvbuff, the offset, and the length as a
2490  * raw string, and return a pointer to that string, allocated using the
2491  * wmem scope. This means a null is appended at the end, but no replacement
2492  * checking is done otherwise. Currently tvb_get_utf_8_string() does not
2493  * replace either, but it might in the future.
2494  *
2495  * Also, this one allows a length of -1 to mean get all, but does not
2496  * allow a negative offset.
2497  */
2498 static inline guint8 *
2499 tvb_get_raw_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint length)
2500 {
2501         guint8 *strbuf;
2502         gint    abs_length = length;
2503
2504         DISSECTOR_ASSERT(offset     >=  0);
2505         DISSECTOR_ASSERT(abs_length >= -1);
2506
2507         if (abs_length < 0)
2508                 abs_length = tvb->length - offset;
2509
2510         tvb_ensure_bytes_exist(tvb, offset, abs_length);
2511         strbuf = (guint8 *)wmem_alloc(scope, abs_length + 1);
2512         tvb_memcpy(tvb, strbuf, offset, abs_length);
2513         strbuf[abs_length] = '\0';
2514         return strbuf;
2515 }
2516
2517 /*
2518  * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2519  * of bytes referred to by the tvbuff, the offset, and the length as an
2520  * ISO 8859/1 string, and return a pointer to a UTF-8 string, allocated
2521  * using the wmem scope.
2522  */
2523 static guint8 *
2524 tvb_get_string_8859_1(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length)
2525 {
2526         const guint8  *ptr;
2527
2528         ptr = ensure_contiguous(tvb, offset, length);
2529         return get_8859_1_string(scope, ptr, length);
2530 }
2531
2532 /*
2533  * Given a wmem scope, a tvbuff, an offset, a length, and a translation
2534  * table, treat the string of bytes referred to by the tvbuff, the offset,
2535  * and the length as a string encoded using one octet per character, with
2536  * octets with the high-order bit clear being ASCII and octets with the
2537  * high-order bit set being mapped by the translation table to 2-byte
2538  * Unicode Basic Multilingual Plane characters (including REPLACEMENT
2539  * CHARACTER), and return a pointer to a UTF-8 string, allocated with the
2540  * wmem scope.
2541  */
2542 static guint8 *
2543 tvb_get_string_unichar2(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length, const gunichar2 table[0x80])
2544 {
2545         const guint8  *ptr;
2546
2547         ptr = ensure_contiguous(tvb, offset, length);
2548         return get_unichar2_string(scope, ptr, length, table);
2549 }
2550
2551 /*
2552  * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2553  * giving the byte order, treat the string of bytes referred to by the
2554  * tvbuff, the offset, and the length as a UCS-2 encoded string in
2555  * the byte order in question, containing characters from the Basic
2556  * Multilingual Plane (plane 0) of Unicode, and return a pointer to a
2557  * UTF-8 string, allocated with the wmem scope.
2558  *
2559  * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN.
2560  *
2561  * Specify length in bytes.
2562  *
2563  * XXX - should map lead and trail surrogate values to REPLACEMENT
2564  * CHARACTERs (0xFFFD)?
2565  * XXX - if there are an odd number of bytes, should put a
2566  * REPLACEMENT CHARACTER at the end.
2567  */
2568 static guint8 *
2569 tvb_get_ucs_2_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2570 {
2571         const guint8  *ptr;
2572
2573         ptr = ensure_contiguous(tvb, offset, length);
2574         return get_ucs_2_string(scope, ptr, length, encoding);
2575 }
2576
2577 /*
2578  * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2579  * giving the byte order, treat the string of bytes referred to by the
2580  * tvbuff, the offset, and the length as a UTF-16 encoded string in
2581  * the byte order in question, and return a pointer to a UTF-8 string,
2582  * allocated with the wmem scope.
2583  *
2584  * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN.
2585  *
2586  * Specify length in bytes.
2587  *
2588  * XXX - should map surrogate errors to REPLACEMENT CHARACTERs (0xFFFD).
2589  * XXX - should map code points > 10FFFF to REPLACEMENT CHARACTERs.
2590  * XXX - if there are an odd number of bytes, should put a
2591  * REPLACEMENT CHARACTER at the end.
2592  */
2593 static guint8 *
2594 tvb_get_utf_16_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2595 {
2596         const guint8  *ptr;
2597
2598         ptr = ensure_contiguous(tvb, offset, length);
2599         return get_utf_16_string(scope, ptr, length, encoding);
2600 }
2601
2602 /*
2603  * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2604  * giving the byte order, treat the string of bytes referred to by the
2605  * tvbuff, the offset, and the length as a UCS-4 encoded string in
2606  * the byte order in question, and return a pointer to a UTF-8 string,
2607  * allocated with the wmem scope.
2608  *
2609  * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
2610  *
2611  * Specify length in bytes
2612  *
2613  * XXX - should map lead and trail surrogate values to a "substitute"
2614  * UTF-8 character?
2615  * XXX - should map code points > 10FFFF to REPLACEMENT CHARACTERs.
2616  * XXX - if the number of bytes isn't a multiple of 4, should put a
2617  * REPLACEMENT CHARACTER at the end.
2618  */
2619 static gchar *
2620 tvb_get_ucs_4_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
2621 {
2622         const guint8 *ptr;
2623
2624         ptr = ensure_contiguous(tvb, offset, length);
2625         return get_ucs_4_string(scope, ptr, length, encoding);
2626 }
2627
2628 gchar *
2629 tvb_get_ts_23_038_7bits_string(wmem_allocator_t *scope, tvbuff_t *tvb,
2630         const gint bit_offset, gint no_of_chars)
2631 {
2632         gint           in_offset = bit_offset >> 3; /* Current pointer to the input buffer */
2633         gint           length = ((no_of_chars + 1) * 7 + (bit_offset & 0x07)) >> 3;
2634         const guint8  *ptr;
2635
2636         DISSECTOR_ASSERT(tvb && tvb->initialized);
2637
2638         ptr = ensure_contiguous(tvb, in_offset, length);
2639         return get_ts_23_038_7bits_string(scope, ptr, bit_offset, no_of_chars);
2640 }
2641
2642 gchar *
2643 tvb_get_ascii_7bits_string(wmem_allocator_t *scope, tvbuff_t *tvb,
2644         const gint bit_offset, gint no_of_chars)
2645 {
2646         gint           in_offset = bit_offset >> 3; /* Current pointer to the input buffer */
2647         gint           length = ((no_of_chars + 1) * 7 + (bit_offset & 0x07)) >> 3;
2648         const guint8  *ptr;
2649
2650         DISSECTOR_ASSERT(tvb && tvb->initialized);
2651
2652         ptr = ensure_contiguous(tvb, in_offset, length);
2653         return get_ascii_7bits_string(scope, ptr, bit_offset, no_of_chars);
2654 }
2655
2656 /*
2657  * Given a wmem scope, a tvbuff, an offset, a length, and a translation
2658  * table, treat the string of bytes referred to by the tvbuff, the offset,
2659  * and the length as a string encoded using one octet per character, with
2660  * octets being mapped by the translation table to 2-byte Unicode Basic
2661  * Multilingual Plane characters (including REPLACEMENT CHARACTER), and
2662  * return a pointer to a UTF-8 string, allocated with the wmem scope.
2663  */
2664 static guint8 *
2665 tvb_get_nonascii_unichar2_string(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length, const gunichar2 table[256])
2666 {
2667         const guint8  *ptr;
2668
2669         ptr = ensure_contiguous(tvb, offset, length);
2670         return get_nonascii_unichar2_string(scope, ptr, length, table);
2671 }
2672
2673 static guint8 *
2674 tvb_get_t61_string(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length)
2675 {
2676         const guint8  *ptr;
2677
2678         ptr = ensure_contiguous(tvb, offset, length);
2679         return get_t61_string(scope, ptr, length);
2680 }
2681
2682 /*
2683  * Given a tvbuff, an offset, a length, and an encoding, allocate a
2684  * buffer big enough to hold a non-null-terminated string of that length
2685  * at that offset, plus a trailing '\0', copy into the buffer the
2686  * string as converted from the appropriate encoding to UTF-8, and
2687  * return a pointer to the string.
2688  */
2689 guint8 *
2690 tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset,
2691                              const gint length, const guint encoding)
2692 {
2693         guint8 *strptr;
2694
2695         DISSECTOR_ASSERT(tvb && tvb->initialized);
2696
2697         /* make sure length = -1 fails */
2698         if (length < 0) {
2699                 THROW(ReportedBoundsError);
2700         }
2701
2702         switch (encoding & ENC_CHARENCODING_MASK) {
2703
2704         case ENC_ASCII:
2705         default:
2706                 /*
2707                  * For now, we treat bogus values as meaning
2708                  * "ASCII" rather than reporting an error,
2709                  * for the benefit of old dissectors written
2710                  * when the last argument to proto_tree_add_item()
2711                  * was a gboolean for the byte order, not an
2712                  * encoding value, and passed non-zero values
2713                  * other than TRUE to mean "little-endian".
2714                  */
2715                 strptr = tvb_get_ascii_string(scope, tvb, offset, length);
2716                 break;
2717
2718         case ENC_UTF_8:
2719                 /*
2720                  * XXX - should map lead and trail surrogate value code
2721                  * points to a "substitute" UTF-8 character?
2722                  * XXX - should map code points > 10FFFF to REPLACEMENT
2723                  * CHARACTERs.
2724                  */
2725                 strptr = tvb_get_utf_8_string(scope, tvb, offset, length);
2726                 break;
2727
2728         case ENC_UTF_16:
2729                 strptr = tvb_get_utf_16_string(scope, tvb, offset, length,
2730                     encoding & ENC_LITTLE_ENDIAN);
2731                 break;
2732
2733         case ENC_UCS_2:
2734                 strptr = tvb_get_ucs_2_string(scope, tvb, offset, length,
2735                     encoding & ENC_LITTLE_ENDIAN);
2736                 break;
2737
2738         case ENC_UCS_4:
2739                 strptr = tvb_get_ucs_4_string(scope, tvb, offset, length,
2740                     encoding & ENC_LITTLE_ENDIAN);
2741                 break;
2742
2743         case ENC_ISO_8859_1:
2744                 /*
2745                  * ISO 8859-1 printable code point values are equal
2746                  * to the equivalent Unicode code point value, so
2747                  * no translation table is needed.
2748                  */
2749                 strptr = tvb_get_string_8859_1(scope, tvb, offset, length);
2750                 break;
2751
2752         case ENC_ISO_8859_2:
2753                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_2);
2754                 break;
2755
2756         case ENC_ISO_8859_3:
2757                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_3);
2758                 break;
2759
2760         case ENC_ISO_8859_4:
2761                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_4);
2762                 break;
2763
2764         case ENC_ISO_8859_5:
2765                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_5);
2766                 break;
2767
2768         case ENC_ISO_8859_6:
2769                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_6);
2770                 break;
2771
2772         case ENC_ISO_8859_7:
2773                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_7);
2774                 break;
2775
2776         case ENC_ISO_8859_8:
2777                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_8);
2778                 break;
2779
2780         case ENC_ISO_8859_9:
2781                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_9);
2782                 break;
2783
2784         case ENC_ISO_8859_10:
2785                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_10);
2786                 break;
2787
2788         case ENC_ISO_8859_11:
2789                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_11);
2790                 break;
2791
2792         case ENC_ISO_8859_13:
2793                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_13);
2794                 break;
2795
2796         case ENC_ISO_8859_14:
2797                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_14);
2798                 break;
2799
2800         case ENC_ISO_8859_15:
2801                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_15);
2802                 break;
2803
2804         case ENC_ISO_8859_16:
2805                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_16);
2806                 break;
2807
2808         case ENC_WINDOWS_1250:
2809                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp1250);
2810                 break;
2811
2812         case ENC_MAC_ROMAN:
2813                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_mac_roman);
2814                 break;
2815
2816         case ENC_CP437:
2817                 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp437);
2818                 break;
2819
2820         case ENC_3GPP_TS_23_038_7BITS:
2821                 {
2822                         gint bit_offset  = offset << 3;
2823                         gint no_of_chars = (length << 3) / 7;
2824                         strptr = tvb_get_ts_23_038_7bits_string(scope, tvb, bit_offset, no_of_chars);
2825                 }
2826                 break;
2827
2828         case ENC_ASCII_7BITS:
2829                 {
2830                         gint bit_offset  = offset << 3;
2831                         gint no_of_chars = (length << 3) / 7;
2832                         strptr = tvb_get_ascii_7bits_string(scope, tvb, bit_offset, no_of_chars);
2833                 }
2834                 break;
2835
2836         case ENC_EBCDIC:
2837                 /*
2838                  * "Common" EBCDIC, covering all characters with the
2839                  * same code point in all Roman-alphabet EBCDIC code
2840                  * pages.
2841                  */
2842                 strptr = tvb_get_nonascii_unichar2_string(scope, tvb, offset, length, charset_table_ebcdic);
2843                 break;
2844
2845         case ENC_EBCDIC_CP037:
2846                 /*
2847                  * EBCDIC code page 037.
2848                  */
2849                 strptr = tvb_get_nonascii_unichar2_string(scope, tvb, offset, length, charset_table_ebcdic_cp037);
2850                 break;
2851
2852         case ENC_T61:
2853                 strptr = tvb_get_t61_string(scope, tvb, offset, length);
2854                 break;
2855         }
2856         return strptr;
2857 }
2858
2859 /*
2860  * This is like tvb_get_string_enc(), except that it handles null-padded
2861  * strings.
2862  *
2863  * Currently, string values are stored as UTF-8 null-terminated strings,
2864  * so nothing needs to be done differently for null-padded strings; we
2865  * could save a little memory by not storing the null padding.
2866  *
2867  * If we ever store string values differently, in a fashion that doesn't
2868  * involve null termination, that might change.
2869  */
2870 guint8 *
2871 tvb_get_stringzpad(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset,
2872                    const gint length, const guint encoding)
2873 {
2874         return tvb_get_string_enc(scope, tvb, offset, length, encoding);
2875 }
2876
2877 /*
2878  * These routines are like the above routines, except that they handle
2879  * null-terminated strings.  They find the length of that string (and
2880  * throw an exception if the tvbuff ends before we find the null), and
2881  * also return through a pointer the length of the string, in bytes,
2882  * including the terminating null (the terminating null being 2 bytes
2883  * for UCS-2 and UTF-16, 4 bytes for UCS-4, and 1 byte for other
2884  * encodings).
2885  */
2886 static guint8 *
2887 tvb_get_ascii_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp)
2888 {
2889         guint          size;
2890         const guint8  *ptr;
2891
2892         size = tvb_strsize(tvb, offset);
2893         ptr  = ensure_contiguous(tvb, offset, size);
2894         /* XXX, conversion between signed/unsigned integer */
2895         if (lengthp)
2896                 *lengthp = size;
2897         return get_ascii_string(scope, ptr, size);
2898 }
2899
2900 static guint8 *
2901 tvb_get_utf_8_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp)
2902 {
2903         guint   size;
2904         guint8 *strptr;
2905
2906         size   = tvb_strsize(tvb, offset);
2907         strptr = (guint8 *)wmem_alloc(scope, size);
2908         tvb_memcpy(tvb, strptr, offset, size);
2909         if (lengthp)
2910                 *lengthp = size;
2911         return strptr;
2912 }
2913
2914 static guint8 *
2915 tvb_get_stringz_8859_1(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp)
2916 {
2917         guint size;
2918         const guint8  *ptr;
2919
2920         size = tvb_strsize(tvb, offset);
2921         ptr = ensure_contiguous(tvb, offset, size);
2922         /* XXX, conversion between signed/unsigned integer */
2923         if (lengthp)
2924                 *lengthp = size;
2925         return get_8859_1_string(scope, ptr, size);
2926 }
2927
2928 static guint8 *
2929 tvb_get_stringz_unichar2(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp, const gunichar2 table[0x80])
2930 {
2931         guint size;
2932         const guint8  *ptr;
2933
2934         size = tvb_strsize(tvb, offset);
2935         ptr = ensure_contiguous(tvb, offset, size);
2936         /* XXX, conversion between signed/unsigned integer */
2937         if (lengthp)
2938                 *lengthp = size;
2939         return get_unichar2_string(scope, ptr, size, table);
2940 }
2941
2942 /*
2943  * Given a tvbuff and an offset, with the offset assumed to refer to
2944  * a null-terminated string, find the length of that string (and throw
2945  * an exception if the tvbuff ends before we find the null), ensure that
2946  * the TVB is flat, and return a pointer to the string (in the TVB).
2947  * Also return the length of the string (including the terminating null)
2948  * through a pointer.
2949  *
2950  * As long as we aren't using composite TVBs, this saves the cycles used
2951  * (often unnecessariliy) in allocating a buffer and copying the string into
2952  * it.  (If we do start using composite TVBs, we may want to replace this
2953  * function with the _ephemeral version.)
2954  */
2955 const guint8 *
2956 tvb_get_const_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
2957 {
2958         guint         size;
2959         const guint8 *strptr;
2960
2961         size   = tvb_strsize(tvb, offset);
2962         strptr = ensure_contiguous(tvb, offset, size);
2963         if (lengthp)
2964                 *lengthp = size;
2965         return strptr;
2966 }
2967
2968 static gchar *
2969 tvb_get_ucs_2_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2970 {
2971         gint           size;    /* Number of bytes in string */
2972         const guint8  *ptr;
2973
2974         size = tvb_unicode_strsize(tvb, offset);
2975         ptr = ensure_contiguous(tvb, offset, size);
2976         /* XXX, conversion between signed/unsigned integer */
2977         if (lengthp)
2978                 *lengthp = size;
2979         return get_ucs_2_string(scope, ptr, size, encoding);
2980 }
2981
2982 static gchar *
2983 tvb_get_utf_16_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2984 {
2985         gint           size;
2986         const guint8  *ptr;
2987
2988         size = tvb_unicode_strsize(tvb, offset);
2989         ptr = ensure_contiguous(tvb, offset, size);
2990         /* XXX, conversion between signed/unsigned integer */
2991         if (lengthp)
2992                 *lengthp = size;
2993         return get_utf_16_string(scope, ptr, size, encoding);
2994 }
2995
2996 static gchar *
2997 tvb_get_ucs_4_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
2998 {
2999         gint           size;
3000         gunichar       uchar;
3001         const guint8  *ptr;
3002
3003         size = 0;
3004         do {
3005                 /* Endianness doesn't matter when looking for null */
3006                 uchar = tvb_get_ntohl(tvb, offset + size);
3007                 size += 4;
3008         } while(uchar != 0);
3009
3010         ptr = ensure_contiguous(tvb, offset, size);
3011         /* XXX, conversion between signed/unsigned integer */
3012         if (lengthp)
3013                 *lengthp = size;
3014         return get_ucs_4_string(scope, ptr, size, encoding);
3015 }
3016
3017 static guint8 *
3018 tvb_get_nonascii_unichar2_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp, const gunichar2 table[256])
3019 {
3020         guint          size;
3021         const guint8  *ptr;
3022
3023         size = tvb_strsize(tvb, offset);
3024         ptr  = ensure_contiguous(tvb, offset, size);
3025         /* XXX, conversion between signed/unsigned integer */
3026         if (lengthp)
3027                 *lengthp = size;
3028         return get_nonascii_unichar2_string(scope, ptr, size, table);
3029 }
3030
3031 static guint8 *
3032 tvb_get_t61_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp)
3033 {
3034         guint          size;
3035         const guint8  *ptr;
3036
3037         size = tvb_strsize(tvb, offset);
3038         ptr  = ensure_contiguous(tvb, offset, size);
3039         /* XXX, conversion between signed/unsigned integer */
3040         if (lengthp)
3041                 *lengthp = size;
3042         return get_t61_string(scope, ptr, size);
3043 }
3044
3045 guint8 *
3046 tvb_get_stringz_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
3047 {
3048         guint8 *strptr;
3049
3050         DISSECTOR_ASSERT(tvb && tvb->initialized);
3051
3052         switch (encoding & ENC_CHARENCODING_MASK) {
3053
3054         case ENC_ASCII:
3055         default:
3056                 /*
3057                  * For now, we treat bogus values as meaning
3058                  * "ASCII" rather than reporting an error,
3059                  * for the benefit of old dissectors written
3060                  * when the last argument to proto_tree_add_item()
3061                  * was a gboolean for the byte order, not an
3062                  * encoding value, and passed non-zero values
3063                  * other than TRUE to mean "little-endian".
3064                  */
3065                 strptr = tvb_get_ascii_stringz(scope, tvb, offset, lengthp);
3066                 break;
3067
3068         case ENC_UTF_8:
3069                 /*
3070                  * XXX - should map all invalid UTF-8 sequences
3071                  * to a "substitute" UTF-8 character.
3072                  * XXX - should map code points > 10FFFF to REPLACEMENT
3073                  * CHARACTERs.
3074                  */
3075                 strptr = tvb_get_utf_8_stringz(scope, tvb, offset, lengthp);
3076                 break;
3077
3078         case ENC_UTF_16:
3079                 strptr = tvb_get_utf_16_stringz(scope, tvb, offset, lengthp,
3080                     encoding & ENC_LITTLE_ENDIAN);
3081                 break;
3082
3083         case ENC_UCS_2:
3084                 strptr = tvb_get_ucs_2_stringz(scope, tvb, offset, lengthp,
3085                     encoding & ENC_LITTLE_ENDIAN);
3086                 break;
3087
3088         case ENC_UCS_4:
3089                 strptr = tvb_get_ucs_4_stringz(scope, tvb, offset, lengthp,
3090                     encoding & ENC_LITTLE_ENDIAN);
3091                 break;
3092
3093         case ENC_ISO_8859_1:
3094                 /*
3095                  * ISO 8859-1 printable code point values are equal
3096                  * to the equivalent Unicode code point value, so
3097                  * no translation table is needed.
3098                  */
3099                 strptr = tvb_get_stringz_8859_1(scope, tvb, offset, lengthp);
3100                 break;
3101
3102         case ENC_ISO_8859_2:
3103                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_2);
3104                 break;
3105
3106         case ENC_ISO_8859_3:
3107                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_3);
3108                 break;
3109
3110         case ENC_ISO_8859_4:
3111                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_4);
3112                 break;
3113
3114         case ENC_ISO_8859_5:
3115                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_5);
3116                 break;
3117
3118         case ENC_ISO_8859_6:
3119                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_6);
3120                 break;
3121
3122         case ENC_ISO_8859_7:
3123                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_7);
3124                 break;
3125
3126         case ENC_ISO_8859_8:
3127                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_8);
3128                 break;
3129
3130         case ENC_ISO_8859_9:
3131                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_9);
3132                 break;
3133
3134         case ENC_ISO_8859_10:
3135                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_10);
3136                 break;
3137
3138         case ENC_ISO_8859_11:
3139                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_11);
3140                 break;
3141
3142         case ENC_ISO_8859_13:
3143                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_13);
3144                 break;
3145
3146         case ENC_ISO_8859_14:
3147                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_14);
3148                 break;
3149
3150         case ENC_ISO_8859_15:
3151                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_15);
3152                 break;
3153
3154         case ENC_ISO_8859_16:
3155                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_16);
3156                 break;
3157
3158         case ENC_WINDOWS_1250:
3159                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp1250);
3160                 break;
3161
3162         case ENC_MAC_ROMAN:
3163                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_mac_roman);
3164                 break;
3165
3166         case ENC_CP437:
3167                 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp437);
3168                 break;
3169
3170         case ENC_3GPP_TS_23_038_7BITS:
3171                 REPORT_DISSECTOR_BUG("TS 23.038 7bits has no null character and doesn't support null-terminated strings");
3172                 break;
3173
3174         case ENC_ASCII_7BITS:
3175                 REPORT_DISSECTOR_BUG("tvb_get_stringz_enc function with ENC_ASCII_7BITS not implemented yet");
3176                 break;
3177
3178         case ENC_EBCDIC:
3179                 /*
3180                  * "Common" EBCDIC, covering all characters with the
3181                  * same code point in all Roman-alphabet EBCDIC code
3182                  * pages.
3183                  */
3184                 strptr = tvb_get_nonascii_unichar2_stringz(scope, tvb, offset, lengthp, charset_table_ebcdic);
3185                 break;
3186
3187         case ENC_EBCDIC_CP037:
3188                 /*
3189                  * EBCDIC code page 037.
3190                  */
3191                 strptr = tvb_get_nonascii_unichar2_stringz(scope, tvb, offset, lengthp, charset_table_ebcdic_cp037);
3192                 break;
3193
3194         case ENC_T61:
3195                 strptr = tvb_get_t61_stringz(scope, tvb, offset, lengthp);
3196                 break;
3197         }
3198
3199         return strptr;
3200 }
3201
3202 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
3203  * no more than bufsize number of bytes, including terminating NUL, to buffer.
3204  * Returns length of string (not including terminating NUL), or -1 if the string was
3205  * truncated in the buffer due to not having reached the terminating NUL.
3206  * In this way, it acts like g_snprintf().
3207  *
3208  * bufsize MUST be greater than 0.
3209  *
3210  * When processing a packet where the remaining number of bytes is less
3211  * than bufsize, an exception is not thrown if the end of the packet
3212  * is reached before the NUL is found. If no NUL is found before reaching
3213  * the end of the short packet, -1 is still returned, and the string
3214  * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
3215  * at the correct spot, terminating the string.
3216  *
3217  * *bytes_copied will contain the number of bytes actually copied,
3218  * including the terminating-NUL.
3219  */
3220 static gint
3221 _tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer, gint *bytes_copied)
3222 {
3223         gint     stringlen;
3224         guint    abs_offset = 0;
3225         gint     limit, len = 0;
3226         gboolean decreased_max = FALSE;
3227
3228         /* Only read to end of tvbuff, w/o throwing exception. */
3229         check_offset_length(tvb, offset, -1, &abs_offset, &len);
3230
3231         /* There must at least be room for the terminating NUL. */
3232         DISSECTOR_ASSERT(bufsize != 0);
3233
3234         /* If there's no room for anything else, just return the NUL. */
3235         if (bufsize == 1) {
3236                 buffer[0] = 0;
3237                 *bytes_copied = 1;
3238                 return 0;
3239         }
3240
3241         /* check_offset_length() won't throw an exception if we're
3242          * looking at the byte immediately after the end of the tvbuff. */
3243         if (len == 0) {
3244                 THROW(ReportedBoundsError);
3245         }
3246
3247         /* This should not happen because check_offset_length() would
3248          * have already thrown an exception if 'offset' were out-of-bounds.
3249          */
3250         DISSECTOR_ASSERT(len != -1);
3251
3252         /*
3253          * If we've been passed a negative number, bufsize will
3254          * be huge.
3255          */
3256         DISSECTOR_ASSERT(bufsize <= G_MAXINT);
3257
3258         if ((guint)len < bufsize) {
3259                 limit = len;
3260                 decreased_max = TRUE;
3261         }
3262         else {
3263                 limit = bufsize;
3264         }
3265
3266         stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
3267         /* If NUL wasn't found, copy the data and return -1 */
3268         if (stringlen == -1) {
3269                 tvb_memcpy(tvb, buffer, abs_offset, limit);
3270                 if (decreased_max) {
3271                         buffer[limit] = 0;
3272                         /* Add 1 for the extra NUL that we set at buffer[limit],
3273                          * pretending that it was copied as part of the string. */
3274                         *bytes_copied = limit + 1;
3275                 }
3276                 else {
3277                         *bytes_copied = limit;
3278                 }
3279                 return -1;
3280         }
3281
3282         /* Copy the string to buffer */
3283         tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
3284         *bytes_copied = stringlen + 1;
3285         return stringlen;
3286 }
3287
3288 /* Looks for a stringz (NUL-terminated string) in tvbuff and copies
3289  * no more than bufsize number of bytes, including terminating NUL, to buffer.
3290  * Returns length of string (not including terminating NUL), or -1 if the string was
3291  * truncated in the buffer due to not having reached the terminating NUL.
3292  * In this way, it acts like g_snprintf().
3293  *
3294  * When processing a packet where the remaining number of bytes is less
3295  * than bufsize, an exception is not thrown if the end of the packet
3296  * is reached before the NUL is found. If no NUL is found before reaching
3297  * the end of the short packet, -1 is still returned, and the string
3298  * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
3299  * at the correct spot, terminating the string.
3300  */
3301 gint
3302 tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8 *buffer)
3303 {
3304         gint bytes_copied;
3305
3306         DISSECTOR_ASSERT(tvb && tvb->initialized);
3307
3308         return _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
3309 }
3310
3311 /* Like tvb_get_nstringz(), but never returns -1. The string is guaranteed to
3312  * have a terminating NUL. If the string was truncated when copied into buffer,
3313  * a NUL is placed at the end of buffer to terminate it.
3314  */
3315 gint
3316 tvb_get_nstringz0(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer)
3317 {
3318         gint    len, bytes_copied;
3319
3320         DISSECTOR_ASSERT(tvb && tvb->initialized);
3321
3322         len = _tvb_get_nstringz(tvb, offset, bufsize, buffer, &bytes_copied);
3323
3324         if (len == -1) {
3325                 buffer[bufsize - 1] = 0;
3326                 return bytes_copied - 1;
3327         }
3328         else {
3329                 return len;
3330         }
3331 }
3332
3333
3334 static ws_mempbrk_pattern pbrk_crlf;
3335 /*
3336  * Given a tvbuff, an offset into the tvbuff, and a length that starts
3337  * at that offset (which may be -1 for "all the way to the end of the
3338  * tvbuff"), find the end of the (putative) line that starts at the
3339  * specified offset in the tvbuff, going no further than the specified
3340  * length.
3341  *
3342  * Return the length of the line (not counting the line terminator at
3343  * the end), or, if we don't find a line terminator:
3344  *
3345  * if "desegment" is true, return -1;
3346  *
3347  * if "desegment" is false, return the amount of data remaining in
3348  * the buffer.
3349  *
3350  * Set "*next_offset" to the offset of the character past the line
3351  * terminator, or past the end of the buffer if we don't find a line
3352  * terminator.  (It's not set if we return -1.)
3353  */
3354 gint
3355 tvb_find_line_end(tvbuff_t *tvb, const gint offset, int len, gint *next_offset, const gboolean desegment)
3356 {
3357         gint   eob_offset;
3358         gint   eol_offset;
3359         int    linelen;
3360         guchar found_needle = 0;
3361         static gboolean compiled = FALSE;
3362
3363         DISSECTOR_ASSERT(tvb && tvb->initialized);
3364
3365         if (len == -1) {
3366                 len = _tvb_captured_length_remaining(tvb, offset);
3367                 /* if offset is past the end of the tvbuff, len is now 0 */
3368         }
3369
3370         eob_offset = offset + len;
3371
3372         if (!compiled) {
3373                 ws_mempbrk_compile(&pbrk_crlf, "\r\n");
3374                 compiled = TRUE;
3375         }
3376
3377         /*
3378          * Look either for a CR or an LF.
3379          */
3380         eol_offset = tvb_ws_mempbrk_pattern_guint8(tvb, offset, len, &pbrk_crlf, &found_needle);
3381         if (eol_offset == -1) {
3382                 /*
3383                  * No CR or LF - line is presumably continued in next packet.
3384                  */
3385                 if (desegment) {
3386                         /*
3387                          * Tell our caller we saw no EOL, so they can
3388                          * try to desegment and get the entire line
3389                          * into one tvbuff.
3390                          */
3391                         return -1;
3392                 } else {
3393                         /*
3394                          * Pretend the line runs to the end of the tvbuff.
3395                          */
3396                         linelen = eob_offset - offset;
3397                         if (next_offset)
3398                                 *next_offset = eob_offset;
3399                 }
3400         } else {
3401                 /*
3402                  * Find the number of bytes between the starting offset
3403                  * and the CR or LF.
3404                  */
3405                 linelen = eol_offset - offset;
3406
3407                 /*
3408                  * Is it a CR?
3409                  */
3410                 if (found_needle == '\r') {
3411                         /*
3412                          * Yes - is it followed by an LF?
3413                          */
3414                         if (eol_offset + 1 >= eob_offset) {
3415                                 /*
3416                                  * Dunno - the next byte isn't in this
3417                                  * tvbuff.
3418                                  */
3419                                 if (desegment) {
3420                                         /*
3421                                          * We'll return -1, although that
3422                                          * runs the risk that if the line
3423                                          * really *is* terminated with a CR,
3424                                          * we won't properly dissect this
3425                                          * tvbuff.
3426                                          *
3427                                          * It's probably more likely that
3428                                          * the line ends with CR-LF than
3429                                          * that it ends with CR by itself.
3430                                          */
3431                                         return -1;
3432                                 }
3433                         } else {
3434                                 /*
3435                                  * Well, we can at least look at the next
3436                                  * byte.
3437                                  */
3438                                 if (tvb_get_guint8(tvb, eol_offset + 1) == '\n') {
3439                                         /*
3440                                          * It's an LF; skip over the CR.
3441                                          */
3442                                         eol_offset++;
3443                                 }
3444                         }
3445                 }
3446
3447                 /*
3448                  * Return the offset of the character after the last
3449                  * character in the line, skipping over the last character
3450                  * in the line terminator.
3451                  */
3452                 if (next_offset)
3453                         *next_offset = eol_offset + 1;
3454         }
3455         return linelen;
3456 }
3457
3458 static ws_mempbrk_pattern pbrk_crlf_dquote;
3459 /*
3460  * Given a tvbuff, an offset into the tvbuff, and a length that starts
3461  * at that offset (which may be -1 for "all the way to the end of the
3462  * tvbuff"), find the end of the (putative) line that starts at the
3463  * specified offset in the tvbuff, going no further than the specified
3464  * length.
3465  *
3466  * However, treat quoted strings inside the buffer specially - don't
3467  * treat newlines in quoted strings as line terminators.
3468  *
3469  * Return the length of the line (not counting the line terminator at
3470  * the end), or the amount of data remaining in the buffer if we don't
3471  * find a line terminator.
3472  *
3473  * Set "*next_offset" to the offset of the character past the line
3474  * terminator, or past the end of the buffer if we don't find a line
3475  * terminator.
3476  */
3477 gint
3478 tvb_find_line_end_unquoted(tvbuff_t *tvb, const gint offset, int len, gint *next_offset)
3479 {
3480         gint     cur_offset, char_offset;
3481         gboolean is_quoted;
3482         guchar   c = 0;
3483         gint     eob_offset;
3484         int      linelen;
3485         static gboolean compiled = FALSE;
3486
3487         DISSECTOR_ASSERT(tvb && tvb->initialized);
3488
3489         if (len == -1)
3490                 len = _tvb_captured_length_remaining(tvb, offset);
3491
3492         if (!compiled) {
3493                 ws_mempbrk_compile(&pbrk_crlf_dquote, "\r\n\"");
3494                 compiled = TRUE;
3495         }
3496
3497         /*
3498          * XXX - what if "len" is still -1, meaning "offset is past the
3499          * end of the tvbuff"?
3500          */
3501         eob_offset = offset + len;
3502
3503         cur_offset = offset;
3504         is_quoted  = FALSE;
3505         for (;;) {
3506                         /*
3507                  * Is this part of the string quoted?
3508                  */
3509                 if (is_quoted) {
3510                         /*
3511                          * Yes - look only for the terminating quote.
3512                          */
3513                         char_offset = tvb_find_guint8(tvb, cur_offset, len,
3514                                 '"');
3515                 } else {
3516                         /*
3517                          * Look either for a CR, an LF, or a '"'.
3518                          */
3519                         char_offset = tvb_ws_mempbrk_pattern_guint8(tvb, cur_offset, len, &pbrk_crlf_dquote, &c);
3520                 }
3521                 if (char_offset == -1) {
3522                         /*
3523                          * Not found - line is presumably continued in
3524                          * next packet.
3525                          * We pretend the line runs to the end of the tvbuff.
3526                          */
3527                         linelen = eob_offset - offset;
3528                         if (next_offset)
3529                                 *next_offset = eob_offset;
3530                         break;
3531                 }
3532
3533                 if (is_quoted) {
3534                         /*
3535                          * We're processing a quoted string.
3536                          * We only looked for ", so we know it's a ";
3537                          * as we're processing a quoted string, it's a
3538                          * closing quote.
3539                          */
3540                         is_quoted = FALSE;
3541                 } else {
3542                         /*
3543                          * OK, what is it?
3544                          */
3545                         if (c == '"') {
3546                                 /*
3547                                  * Un-quoted "; it begins a quoted
3548                                  * string.
3549                                  */
3550                                 is_quoted = TRUE;
3551                         } else {
3552                                 /*
3553                                  * It's a CR or LF; we've found a line
3554                                  * terminator.
3555                                  *
3556                                  * Find the number of bytes between the
3557                                  * starting offset and the CR or LF.
3558                                  */
3559                                 linelen = char_offset - offset;
3560
3561                                 /*
3562                                  * Is it a CR?
3563                                  */
3564                                 if (c == '\r') {
3565                                         /*
3566                                          * Yes; is it followed by an LF?
3567                                          */
3568                                         if (char_offset + 1 < eob_offset &&
3569                                                 tvb_get_guint8(tvb, char_offset + 1)
3570                                                   == '\n') {
3571                                                 /*
3572                                                  * Yes; skip over the CR.
3573                                                  */
3574                                                 char_offset++;
3575                                         }
3576                                 }
3577
3578                                 /*
3579                                  * Return the offset of the character after
3580                                  * the last character in the line, skipping
3581                                  * over the last character in the line
3582                                  * terminator, and quit.
3583                                  */
3584                                 if (next_offset)
3585                                         *next_offset = char_offset + 1;
3586                                 break;
3587                         }
3588                 }
3589
3590                 /*
3591                  * Step past the character we found.
3592                  */
3593                 cur_offset = char_offset + 1;
3594                 if (cur_offset >= eob_offset) {
3595                         /*
3596                          * The character we found was the last character
3597                          * in the tvbuff - line is presumably continued in
3598                          * next packet.
3599                          * We pretend the line runs to the end of the tvbuff.
3600                          */
3601                         linelen = eob_offset - offset;
3602                         if (next_offset)
3603                                 *next_offset = eob_offset;
3604                         break;
3605                 }
3606         }
3607         return linelen;
3608 }
3609
3610 /*
3611  * Copied from the mgcp dissector. (This function should be moved to /epan )
3612  * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
3613  *                                character following offset or offset + maxlength -1 whichever
3614  *                                is smaller.
3615  *
3616  * Parameters:
3617  * tvb - The tvbuff in which we are skipping whitespace.
3618  * offset - The offset in tvb from which we begin trying to skip whitespace.
3619  * maxlength - The maximum distance from offset that we may try to skip
3620  * whitespace.
3621  *
3622  * Returns: The position in tvb of the first non-whitespace
3623  *                      character following offset or offset + maxlength -1 whichever
3624  *                      is smaller.
3625  */
3626 gint
3627 tvb_skip_wsp(tvbuff_t *tvb, const gint offset, const gint maxlength)
3628 {
3629         gint   counter = offset;
3630         gint   end, tvb_len;
3631         guint8 tempchar;
3632
3633         DISSECTOR_ASSERT(tvb && tvb->initialized);
3634
3635         /* Get the length remaining */
3636         /*tvb_len = tvb_captured_length(tvb);*/
3637         tvb_len = tvb->length;
3638
3639         end     = offset + maxlength;
3640         if (end >= tvb_len)
3641         {
3642                 end = tvb_len;
3643         }
3644
3645         /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
3646         for (counter = offset;
3647                  counter < end &&
3648                   ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
3649                   tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
3650                  counter++);
3651
3652         return (counter);
3653 }
3654
3655 gint
3656 tvb_skip_wsp_return(tvbuff_t *tvb, const gint offset)
3657 {
3658         gint   counter = offset;
3659         guint8 tempchar;
3660
3661         DISSECTOR_ASSERT(tvb && tvb->initialized);
3662
3663         for (counter = offset; counter > 0 &&
3664                 ((tempchar = tvb_get_guint8(tvb,counter)) == ' ' ||
3665                 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
3666         counter++;
3667
3668         return (counter);
3669 }
3670
3671 int
3672 tvb_skip_guint8(tvbuff_t *tvb, int offset, const int maxlength, const guint8 ch)
3673 {
3674         int end, tvb_len;
3675
3676         DISSECTOR_ASSERT(tvb && tvb->initialized);
3677
3678         /* Get the length remaining */
3679         /*tvb_len = tvb_captured_length(tvb);*/
3680         tvb_len = tvb->length;
3681
3682         end     = offset + maxlength;
3683         if (end >= tvb_len)
3684                 end = tvb_len;
3685
3686         while (offset < end) {
3687                 guint8 tempch = tvb_get_guint8(tvb, offset);
3688
3689                 if (tempch != ch)
3690                         break;
3691                 offset++;
3692         }
3693
3694         return offset;
3695 }
3696
3697 /*
3698  * Format a bunch of data from a tvbuff as bytes, returning a pointer
3699  * to the string with the formatted data, with "punct" as a byte
3700  * separator.
3701  */
3702 gchar *
3703 tvb_bytes_to_str_punct(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint len, const gchar punct)
3704 {
3705         return bytestring_to_str(scope, ensure_contiguous(tvb, offset, len), len, punct);
3706 }
3707
3708
3709 /*
3710  * Given a tvbuff, an offset into the tvbuff, and a length that starts
3711  * at that offset (which may be -1 for "all the way to the end of the
3712  * tvbuff"), fetch BCD encoded digits from a tvbuff starting from either
3713  * the low or high half byte, formating the digits according to an input digit set,
3714  * if NUll a default digit set of 0-9 returning "?" for overdecadic digits will be used.
3715  * A pointer to the packet scope allocated string will be returned.
3716  * Note a tvbuff content of 0xf is considered a 'filler' and will end the conversion.
3717  */
3718 static const dgt_set_t Dgt1_9_bcd = {
3719         {
3720                 /*  0   1   2   3   4   5   6   7   8   9   a   b   c   d   e  f*/
3721                 '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?','?'
3722         }
3723 };
3724 const gchar *
3725 tvb_bcd_dig_to_wmem_packet_str(tvbuff_t *tvb, const gint offset, const gint len, const dgt_set_t *dgt, gboolean skip_first)
3726 {
3727         int     length;
3728         guint8  octet;
3729         int     i        = 0;
3730         char   *digit_str;
3731         gint    t_offset = offset;
3732
3733         DISSECTOR_ASSERT(tvb && tvb->initialized);
3734
3735         if (!dgt)
3736                 dgt = &Dgt1_9_bcd;
3737
3738         if (len == -1) {
3739                 /*length = tvb_captured_length(tvb);*/
3740                 length = tvb->length;
3741                 if (length < offset) {
3742                         return "";
3743                 }
3744         } else {
3745                 length = offset + len;
3746         }
3747         digit_str = (char *)wmem_alloc(wmem_packet_scope(), (length - offset)*2+1);
3748
3749         while (t_offset < length) {
3750
3751                 octet = tvb_get_guint8(tvb,t_offset);
3752                 if (!skip_first) {
3753                         digit_str[i] = dgt->out[octet & 0x0f];
3754                         i++;
3755                 }
3756                 skip_first = FALSE;
3757
3758                 /*
3759                  * unpack second value in byte
3760                  */
3761                 octet = octet >> 4;
3762
3763                 if (t_offset == length - 1 && octet == 0x0f) {
3764                         /*
3765                          * This is the last octet, and the low-order
3766                          * nibble is 0xf, so we have an odd number of
3767                          * digits, and this is a filler digit.  Ignore
3768                          * it.
3769                          */
3770                         break;
3771                 }
3772
3773                 digit_str[i] = dgt->out[octet & 0x0f];
3774                 i++;
3775                 t_offset++;
3776
3777         }
3778         digit_str[i]= '\0';
3779         return digit_str;
3780
3781 }
3782
3783 /*
3784  * Format a bunch of data from a tvbuff as bytes, returning a pointer
3785  * to the string with the formatted data.
3786  */
3787 gchar *tvb_bytes_to_str(wmem_allocator_t *allocator, tvbuff_t *tvb,
3788     const gint offset, const gint len)
3789 {
3790         return bytes_to_str(allocator, ensure_contiguous(tvb, offset, len), len);
3791 }
3792
3793 /* Find a needle tvbuff within a haystack tvbuff. */
3794 gint
3795 tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, const gint haystack_offset)
3796 {
3797         guint         haystack_abs_offset = 0, haystack_abs_length = 0;
3798         const guint8 *haystack_data;
3799         const guint8 *needle_data;
3800         const guint   needle_len = needle_tvb->length;
3801         const guint8 *location;
3802
3803         DISSECTOR_ASSERT(haystack_tvb && haystack_tvb->initialized);
3804
3805         if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
3806                 return -1;
3807         }
3808
3809         /* Get pointers to the tvbuffs' data. */
3810         haystack_data = ensure_contiguous(haystack_tvb, 0, -1);
3811         needle_data   = ensure_contiguous(needle_tvb, 0, -1);
3812
3813         check_offset_length(haystack_tvb, haystack_offset, -1,
3814                         &haystack_abs_offset, &haystack_abs_length);
3815
3816         location = epan_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
3817                         needle_data, needle_len);
3818
3819         if (location) {
3820                 return (gint) (location - haystack_data);
3821         }
3822
3823         return -1;
3824 }
3825
3826 gint
3827 tvb_raw_offset(tvbuff_t *tvb)
3828 {
3829         return ((tvb->raw_offset==-1) ? (tvb->raw_offset = tvb_offset_from_real_beginning(tvb)) : tvb->raw_offset);
3830 }
3831
3832 void
3833 tvb_set_fragment(tvbuff_t *tvb)
3834 {
3835         tvb->flags |= TVBUFF_FRAGMENT;
3836 }
3837
3838 struct tvbuff *
3839 tvb_get_ds_tvb(tvbuff_t *tvb)
3840 {
3841         return(tvb->ds_tvb);
3842 }
3843
3844 guint
3845 tvb_get_varint(tvbuff_t *tvb, guint offset, guint maxlen, guint64 *value, const guint encoding)
3846 {
3847         *value = 0;
3848
3849         if (encoding & ENC_VARINT_PROTOBUF) {
3850                 guint i;
3851                 guint64 b; /* current byte */
3852
3853                 for (i = 0; ((i < FT_VARINT_MAX_LEN) && (i < maxlen)); ++i) {
3854                         b = tvb_get_guint8(tvb, offset++);
3855                         *value |= ((b & 0x7F) << (i * 7)); /* add lower 7 bits to val */
3856
3857                         if (b < 0x80) {
3858                                 /* end successfully becauseof last byte's msb(most significant bit) is zero */
3859                                 return i + 1;
3860                         }
3861                 }
3862         } else if (encoding & ENC_VARINT_QUIC) {
3863
3864                 /* calculate variable length */
3865                 *value = tvb_get_guint8(tvb, offset);
3866                 switch((*value) >> 6) {
3867                 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
3868                         (*value) &= 0x3F;
3869                         return 1;
3870                 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
3871                         *value = tvb_get_ntohs(tvb, offset) & 0x3FFF;
3872                         return 2;
3873                 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
3874                         *value = tvb_get_ntohl(tvb, offset) & 0x3FFFFFFF;
3875                         return 4;
3876                 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
3877                         *value = tvb_get_ntoh64(tvb, offset) & G_GUINT64_CONSTANT(0x3FFFFFFFFFFFFFFF);
3878                         return 8;
3879                 default: /* No Possible */
3880                         g_assert_not_reached();
3881                         break;
3882                 }
3883
3884         }
3885
3886         return 0; /* 10 bytes scanned, but no bytes' msb is zero */
3887 }
3888
3889 /*
3890  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
3891  *
3892  * Local variables:
3893  * c-basic-offset: 8
3894  * tab-width: 8
3895  * indent-tabs-mode: t
3896  * End:
3897  *
3898  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3899  * :indentSize=8:tabSize=8:noTabs=false:
3900  */