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