Bug Summary

File:epan/tvbuff.c
Warning:line 430, column 10
Potential leak of memory pointed to by 'buf'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name tvbuff.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /usr/include/lua5.4 -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-12-11-100311-3573-1 -x c /builds/wireshark/wireshark/epan/tvbuff.c
1/* tvbuff.c
2 *
3 * Testy, Virtual(-izable) Buffer of uint8_t*'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 <[email protected]>
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 <[email protected]>
19 * Copyright 1998 Gerald Combs
20 *
21 * SPDX-License-Identifier: GPL-2.0-or-later
22 */
23
24#include "config.h"
25
26#include <string.h>
27#include <stdio.h>
28#include <errno(*__errno_location ()).h>
29
30#include <glib.h>
31
32#include "wsutil/pint.h"
33#include "wsutil/sign_ext.h"
34#include "wsutil/strtoi.h"
35#include "wsutil/unicode-utils.h"
36#include "wsutil/nstime.h"
37#include "wsutil/time_util.h"
38#include <wsutil/ws_assert.h>
39#include "tvbuff.h"
40#include "tvbuff-int.h"
41#include "strutil.h"
42#include "to_str.h"
43#include "charsets.h"
44#include "proto.h" /* XXX - only used for DISSECTOR_ASSERT, probably a new header file? */
45#include "exceptions.h"
46
47#include <time.h>
48
49static uint64_t
50_tvb_get_bits64(tvbuff_t *tvb, unsigned bit_offset, const int total_no_of_bits);
51
52static uint64_t
53_tvb_get_bits64_le(tvbuff_t *tvb, unsigned bit_offset, const int total_no_of_bits);
54
55static inline int
56_tvb_captured_length_remaining(const tvbuff_t *tvb, const int offset);
57
58static inline const uint8_t*
59ensure_contiguous(tvbuff_t *tvb, const int offset, const int length);
60
61static inline uint8_t *
62tvb_get_raw_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int length);
63
64tvbuff_t *
65tvb_new(const struct tvb_ops *ops)
66{
67 tvbuff_t *tvb;
68 size_t size = ops->tvb_size;
69
70 ws_assert(size >= sizeof(*tvb))do { if ((1) && !(size >= sizeof(*tvb))) ws_log_fatal_full
("", LOG_LEVEL_ERROR, "epan/tvbuff.c", 70, __func__, "assertion failed: %s"
, "size >= sizeof(*tvb)"); } while (0)
;
71
72 tvb = (tvbuff_t *) g_slice_alloc(size);
73
74 tvb->next = NULL((void*)0);
75 tvb->ops = ops;
76 tvb->initialized = false0;
77 tvb->flags = 0;
78 tvb->length = 0;
79 tvb->reported_length = 0;
80 tvb->contained_length = 0;
81 tvb->real_data = NULL((void*)0);
82 tvb->raw_offset = -1;
83 tvb->ds_tvb = NULL((void*)0);
84
85 return tvb;
86}
87
88static void
89tvb_free_internal(tvbuff_t *tvb)
90{
91 size_t size;
92
93 DISSECTOR_ASSERT(tvb)((void) ((tvb) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 93, "tvb"))))
;
94
95 if (tvb->ops->tvb_free)
96 tvb->ops->tvb_free(tvb);
97
98 size = tvb->ops->tvb_size;
99
100 g_slice_free1(size, tvb);
101}
102
103/* XXX: just call tvb_free_chain();
104 * Not removed so that existing dissectors using tvb_free() need not be changed.
105 * I'd argue that existing calls to tvb_free() should have actually been
106 * calls to tvb_free_chain() although the calls were OK as long as no
107 * subsets, etc had been created on the tvb. */
108void
109tvb_free(tvbuff_t *tvb)
110{
111 tvb_free_chain(tvb);
112}
113
114void
115tvb_free_chain(tvbuff_t *tvb)
116{
117 tvbuff_t *next_tvb;
118 DISSECTOR_ASSERT(tvb)((void) ((tvb) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 118, "tvb"))))
;
119 while (tvb) {
120 next_tvb = tvb->next;
121 tvb_free_internal(tvb);
122 tvb = next_tvb;
123 }
124}
125
126tvbuff_t *
127tvb_new_chain(tvbuff_t *parent, tvbuff_t *backing)
128{
129 tvbuff_t *tvb = tvb_new_proxy(backing);
130
131 tvb_add_to_chain(parent, tvb);
132 return tvb;
133}
134
135void
136tvb_add_to_chain(tvbuff_t *parent, tvbuff_t *child)
137{
138 tvbuff_t *tmp;
139
140 DISSECTOR_ASSERT(parent)((void) ((parent) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 140, "parent"))))
;
141 DISSECTOR_ASSERT(child)((void) ((child) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 141, "child"))))
;
142
143 while (child) {
144 tmp = child;
145 child = child->next;
146
147 tmp->next = parent->next;
148 parent->next = tmp;
149 }
150}
151
152/*
153 * Check whether that offset goes more than one byte past the
154 * end of the buffer.
155 *
156 * If not, return 0; otherwise, return exception
157 */
158static inline int
159validate_offset(const tvbuff_t *tvb, const unsigned abs_offset)
160{
161 if (G_LIKELY(abs_offset <= tvb->length)(abs_offset <= tvb->length)) {
162 /* It's OK. */
163 return 0;
164 }
165
166 /*
167 * It's not OK, but why? Which boundaries is it
168 * past?
169 */
170 if (abs_offset <= tvb->contained_length) {
171 /*
172 * It's past the captured length, but not past
173 * the reported end of any parent tvbuffs from
174 * which this is constructed, or the reported
175 * end of this tvbuff, so it's out of bounds
176 * solely because we're past the end of the
177 * captured data.
178 */
179 return BoundsError1;
180 }
181
182 /*
183 * There's some actual packet boundary, not just the
184 * artificial boundary imposed by packet slicing, that
185 * we're past.
186 */
187
188 if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
189 /*
190 * This tvbuff is the first fragment of a larger
191 * packet that hasn't been reassembled, so we
192 * assume that's the source of the problem - if
193 * we'd reassembled the packet, we wouldn't have
194 * gone past the end.
195 *
196 * That might not be true, but for at least
197 * some forms of reassembly, such as IP
198 * reassembly, you don't know how big the
199 * reassembled packet is unless you reassemble
200 * it, so, in those cases, we can't determine
201 * whether we would have gone past the end
202 * had we reassembled the packet.
203 */
204 return FragmentBoundsError4;
205 }
206
207 /* OK, we're not an unreassembled fragment (that we know of). */
208 if (abs_offset <= tvb->reported_length) {
209 /*
210 * We're within the bounds of what this tvbuff
211 * purportedly contains, based on some length
212 * value, but we're not within the bounds of
213 * something from which this tvbuff was
214 * extracted, so that length value ran past
215 * the end of some parent tvbuff.
216 */
217 return ContainedBoundsError2;
218 }
219
220 /*
221 * OK, it looks as if we ran past the claimed length
222 * of data.
223 */
224 return ReportedBoundsError3;
225}
226
227static inline int
228compute_offset(const tvbuff_t *tvb, const int offset, unsigned *offset_ptr)
229{
230 if (offset >= 0) {
231 /* Positive offset - relative to the beginning of the packet. */
232 if (G_LIKELY((unsigned) offset <= tvb->length)((unsigned) offset <= tvb->length)) {
233 *offset_ptr = offset;
234 } else if ((unsigned) offset <= tvb->contained_length) {
235 return BoundsError1;
236 } else if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
237 return FragmentBoundsError4;
238 } else if ((unsigned) offset <= tvb->reported_length) {
239 return ContainedBoundsError2;
240 } else {
241 return ReportedBoundsError3;
242 }
243 }
244 else {
245 /* Negative offset - relative to the end of the packet. */
246 /* Prevent UB on 2's complement platforms. All tested compilers
247 * (gcc, clang, MSVC) compile this to a single instruction on
248 * x86, ARM, RISC-V, S390x, SPARC, etc. at -O1 and higher
249 * according to godbolt.org. */
250 unsigned abs_offset = ((unsigned)-(offset + 1)) + 1;
251 if (G_LIKELY(abs_offset <= tvb->length)(abs_offset <= tvb->length)) {
252 *offset_ptr = tvb->length - abs_offset;
253 } else if (abs_offset <= tvb->contained_length) {
254 return BoundsError1;
255 } else if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
256 return FragmentBoundsError4;
257 } else if (abs_offset <= tvb->reported_length) {
258 return ContainedBoundsError2;
259 } else {
260 return ReportedBoundsError3;
261 }
262 }
263
264 return 0;
265}
266
267static inline int
268compute_offset_and_remaining(const tvbuff_t *tvb, const int offset, unsigned *offset_ptr, unsigned *rem_len)
269{
270 int exception;
271
272 exception = compute_offset(tvb, offset, offset_ptr);
273 if (!exception)
274 *rem_len = tvb->length - *offset_ptr;
275
276 return exception;
277}
278
279/* Computes the absolute offset and length based on a possibly-negative offset
280 * and a length that is possible -1 (which means "to the end of the data").
281 * Returns integer indicating whether the offset is in bounds (0) or
282 * not (exception number). The integer ptrs are modified with the new offset,
283 * captured (available) length, and contained length (amount that's present
284 * in the parent tvbuff based on its reported length).
285 * No exception is thrown; on success, we return 0, otherwise we return an
286 * exception for the caller to throw if appropriate.
287 *
288 * XXX - we return success (0), if the offset is positive and right
289 * after the end of the tvbuff (i.e., equal to the length). We do this
290 * so that a dissector constructing a subset tvbuff for the next protocol
291 * will get a zero-length tvbuff, not an exception, if there's no data
292 * left for the next protocol - we want the next protocol to be the one
293 * that gets an exception, so the error is reported as an error in that
294 * protocol rather than the containing protocol. */
295static inline int
296check_offset_length_no_exception(const tvbuff_t *tvb,
297 const int offset, int const length_val,
298 unsigned *offset_ptr, unsigned *length_ptr)
299{
300 unsigned end_offset;
301 int exception;
302
303 DISSECTOR_ASSERT(offset_ptr)((void) ((offset_ptr) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 303, "offset_ptr"
))))
;
304 DISSECTOR_ASSERT(length_ptr)((void) ((length_ptr) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 304, "length_ptr"
))))
;
305
306 /* Compute the offset */
307 exception = compute_offset(tvb, offset, offset_ptr);
308 if (exception)
309 return exception;
310
311 if (length_val < -1) {
312 /* XXX - ReportedBoundsError? */
313 return BoundsError1;
314 }
315
316 /* Compute the length */
317 if (length_val == -1)
318 *length_ptr = tvb->length - *offset_ptr;
319 else
320 *length_ptr = length_val;
321
322 /*
323 * Compute the offset of the first byte past the length.
324 */
325 end_offset = *offset_ptr + *length_ptr;
326
327 /*
328 * Check for an overflow
329 */
330 if (end_offset < *offset_ptr)
331 return BoundsError1;
332
333 return validate_offset(tvb, end_offset);
334}
335
336/* Checks (+/-) offset and length and throws an exception if
337 * either is out of bounds. Sets integer ptrs to the new offset
338 * and length. */
339static inline void
340check_offset_length(const tvbuff_t *tvb,
341 const int offset, int const length_val,
342 unsigned *offset_ptr, unsigned *length_ptr)
343{
344 int exception;
345
346 exception = check_offset_length_no_exception(tvb, offset, length_val, offset_ptr, length_ptr);
347 if (exception)
348 THROW(exception)except_throw(1, (exception), ((void*)0));
349}
350
351void
352tvb_check_offset_length(const tvbuff_t *tvb,
353 const int offset, int const length_val,
354 unsigned *offset_ptr, unsigned *length_ptr)
355{
356 check_offset_length(tvb, offset, length_val, offset_ptr, length_ptr);
357}
358
359static const unsigned char left_aligned_bitmask[] = {
360 0xff,
361 0x80,
362 0xc0,
363 0xe0,
364 0xf0,
365 0xf8,
366 0xfc,
367 0xfe
368};
369
370tvbuff_t *
371tvb_new_octet_aligned(tvbuff_t *tvb, uint32_t bit_offset, int32_t no_of_bits)
372{
373 tvbuff_t *sub_tvb = NULL((void*)0);
374 uint32_t byte_offset;
375 int32_t datalen, i;
376 uint8_t left, right, remaining_bits, *buf;
377 const uint8_t *data;
378
379 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 379, "tvb && tvb->initialized"
))))
;
4
Assuming 'tvb' is non-null
5
Assuming field 'initialized' is true
6
'?' condition is true
380
381 byte_offset = bit_offset >> 3;
382 left = bit_offset % 8; /* for left-shifting */
383 right = 8 - left; /* for right-shifting */
384
385 if (no_of_bits == -1) {
7
Assuming the condition is false
8
Taking false branch
386 datalen = _tvb_captured_length_remaining(tvb, byte_offset);
387 remaining_bits = 0;
388 } else {
389 datalen = no_of_bits >> 3;
390 remaining_bits = no_of_bits % 8;
391 if (remaining_bits) {
9
Assuming 'remaining_bits' is 0
392 datalen++;
393 }
394 }
395
396 /* already aligned -> shortcut */
397 if ((left == 0) && (remaining_bits == 0)) {
10
Assuming 'left' is not equal to 0
398 return tvb_new_subset_length_caplen(tvb, byte_offset, datalen, datalen);
399 }
400
401 DISSECTOR_ASSERT(datalen>0)((void) ((datalen>0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 401, "datalen>0"
))))
;
11
Assuming 'datalen' is > 0
12
'?' condition is true
402
403 /* If at least one trailing byte is available, we must use the content
404 * of that byte for the last shift (i.e. tvb_get_ptr() must use datalen + 1).
405 * If no extra byte is available, the last shifted byte requires
406 * special treatment.
407 */
408 if (_tvb_captured_length_remaining(tvb, byte_offset) > datalen) {
13
Assuming the condition is true
14
Taking true branch
409 data = ensure_contiguous(tvb, byte_offset, datalen + 1); /* tvb_get_ptr */
410
411 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
412 buf = (uint8_t *)g_malloc(datalen);
15
Memory is allocated
413
414 /* shift tvb data bit_offset bits to the left */
415 for (i = 0; i
15.1
'i' is < 'datalen'
< datalen
; i++)
16
Loop condition is true. Entering loop body
19
Assuming 'i' is >= 'datalen'
20
Loop condition is false. Execution continues on line 428
416 buf[i] = (data[i] << left) | (data[i+1] >> right);
17
Assuming right operand of bit shift is less than 32
18
Assuming right operand of bit shift is non-negative but less than 32
417 } else {
418 data = ensure_contiguous(tvb, byte_offset, datalen); /* tvb_get_ptr() */
419
420 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
421 buf = (uint8_t *)g_malloc(datalen);
422
423 /* shift tvb data bit_offset bits to the left */
424 for (i = 0; i < (datalen-1); i++)
425 buf[i] = (data[i] << left) | (data[i+1] >> right);
426 buf[datalen-1] = data[datalen-1] << left; /* set last octet */
427 }
428 buf[datalen-1] &= left_aligned_bitmask[remaining_bits];
429
430 sub_tvb = tvb_new_child_real_data(tvb, buf, datalen, datalen);
21
Potential leak of memory pointed to by 'buf'
431 tvb_set_free_cb(sub_tvb, g_free);
432
433 return sub_tvb;
434}
435
436tvbuff_t *
437tvb_new_octet_right_aligned(tvbuff_t *tvb, uint32_t bit_offset, int32_t no_of_bits)
438{
439 tvbuff_t *sub_tvb = NULL((void*)0);
440 uint32_t byte_offset;
441 int src_len, dst_len, i;
442 uint8_t left, right, remaining_bits, *buf;
443 const uint8_t *data;
444
445 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 445, "tvb && tvb->initialized"
))))
;
446
447 byte_offset = bit_offset / 8;
448 /* right shift to put bits in place and discard least significant bits */
449 right = bit_offset % 8;
450 /* left shift to get most significant bits from next octet */
451 left = 8 - right;
452
453 if (no_of_bits == -1) {
454 dst_len = _tvb_captured_length_remaining(tvb, byte_offset);
455 remaining_bits = 0;
456 } else {
457 dst_len = no_of_bits / 8;
458 remaining_bits = no_of_bits % 8;
459 if (remaining_bits) {
460 dst_len++;
461 }
462 }
463
464 /* already aligned -> shortcut */
465 if ((right == 0) && (remaining_bits == 0)) {
466 return tvb_new_subset_length_caplen(tvb, byte_offset, dst_len, dst_len);
467 }
468
469 DISSECTOR_ASSERT(dst_len>0)((void) ((dst_len>0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 469, "dst_len>0"
))))
;
470
471 if (_tvb_captured_length_remaining(tvb, byte_offset) > dst_len) {
472 /* last octet will get data from trailing octet */
473 src_len = dst_len + 1;
474 } else {
475 /* last octet will be zero padded */
476 src_len = dst_len;
477 }
478
479 data = ensure_contiguous(tvb, byte_offset, src_len); /* tvb_get_ptr */
480
481 /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */
482 buf = (uint8_t *)g_malloc(dst_len);
483
484 for (i = 0; i < (dst_len - 1); i++)
485 buf[i] = (data[i] >> right) | (data[i+1] << left);
486
487 /* Special handling for last octet */
488 buf[i] = (data[i] >> right);
489 /* Shift most significant bits from trailing octet if available */
490 if (src_len > dst_len)
491 buf[i] |= (data[i+1] << left);
492 /* Preserve only remaining bits in last octet if not multiple of 8 */
493 if (remaining_bits)
494 buf[i] &= ((1 << remaining_bits) - 1);
495
496 sub_tvb = tvb_new_child_real_data(tvb, buf, dst_len, dst_len);
497 tvb_set_free_cb(sub_tvb, g_free);
498
499 return sub_tvb;
500}
501
502static tvbuff_t *
503tvb_generic_clone_offset_len(tvbuff_t *tvb, unsigned offset, unsigned len)
504{
505 tvbuff_t *cloned_tvb;
506 uint8_t *data;
507
508 DISSECTOR_ASSERT(tvb_bytes_exist(tvb, offset, len))((void) ((tvb_bytes_exist(tvb, offset, len)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 508, "tvb_bytes_exist(tvb, offset, len)"
))))
;
509
510 data = (uint8_t *) g_malloc(len);
511
512 tvb_memcpy(tvb, data, offset, len);
513
514 cloned_tvb = tvb_new_real_data(data, len, len);
515 tvb_set_free_cb(cloned_tvb, g_free);
516
517 return cloned_tvb;
518}
519
520tvbuff_t *
521tvb_clone_offset_len(tvbuff_t *tvb, unsigned offset, unsigned len)
522{
523 if (tvb->ops->tvb_clone) {
524 tvbuff_t *cloned_tvb;
525
526 cloned_tvb = tvb->ops->tvb_clone(tvb, offset, len);
527 if (cloned_tvb)
528 return cloned_tvb;
529 }
530
531 return tvb_generic_clone_offset_len(tvb, offset, len);
532}
533
534tvbuff_t *
535tvb_clone(tvbuff_t *tvb)
536{
537 return tvb_clone_offset_len(tvb, 0, tvb->length);
538}
539
540unsigned
541tvb_captured_length(const tvbuff_t *tvb)
542{
543 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 543, "tvb && tvb->initialized"
))))
;
544
545 return tvb->length;
546}
547
548/* For tvbuff internal use */
549static inline int
550_tvb_captured_length_remaining(const tvbuff_t *tvb, const int offset)
551{
552 unsigned abs_offset = 0, rem_length;
553 int exception;
554
555 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
556 if (exception)
557 return 0;
558
559 return rem_length;
560}
561
562int
563tvb_captured_length_remaining(const tvbuff_t *tvb, const int offset)
564{
565 unsigned abs_offset = 0, rem_length;
566 int exception;
567
568 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 568, "tvb && tvb->initialized"
))))
;
569
570 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length);
571 if (exception)
572 return 0;
573
574 return rem_length;
575}
576
577unsigned
578tvb_ensure_captured_length_remaining(const tvbuff_t *tvb, const unsigned offset)
579{
580 unsigned rem_length = 0;
581 int exception;
582
583 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 583, "tvb && tvb->initialized"
))))
;
584
585 exception = validate_offset(tvb, offset);
586 if (exception)
587 THROW(exception)except_throw(1, (exception), ((void*)0));
588
589 rem_length = tvb->length - offset;
590
591 if (rem_length == 0) {
592 /*
593 * This routine ensures there's at least one byte available.
594 * There aren't any bytes available, so throw the appropriate
595 * exception.
596 */
597 if (offset < tvb->contained_length) {
598 THROW(BoundsError)except_throw(1, (1), ((void*)0));
599 } else if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
600 THROW(FragmentBoundsError)except_throw(1, (4), ((void*)0));
601 } else if (offset < tvb->reported_length) {
602 THROW(ContainedBoundsError)except_throw(1, (2), ((void*)0));
603 } else {
604 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
605 }
606 }
607 return rem_length;
608}
609
610/* Validates that 'length' bytes are available starting from
611 * offset (pos/neg). Does not throw an exception. */
612bool_Bool
613tvb_bytes_exist(const tvbuff_t *tvb, const int offset, const int length)
614{
615 unsigned abs_offset = 0, abs_length;
616 int exception;
617
618 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 618, "tvb && tvb->initialized"
))))
;
619
620 /*
621 * Negative lengths are not possible and indicate a bug (e.g. arithmetic
622 * error or an overly large value from packet data).
623 */
624 if (length < 0)
625 return false0;
626
627 exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
628 if (exception)
629 return false0;
630
631 return true1;
632}
633
634/* Validates that 'length' bytes, where 'length' is a 64-bit unsigned
635 * integer, are available starting from offset (pos/neg). Throws an
636 * exception if they aren't. */
637void
638tvb_ensure_bytes_exist64(const tvbuff_t *tvb, const unsigned offset, const uint64_t length)
639{
640 /*
641 * Make sure the value fits in a signed integer; if not, assume
642 * that means that it's too big.
643 */
644 if (length > INT_MAX2147483647) {
645 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
646 }
647
648 /* OK, now cast it and try it with tvb_ensure_bytes_exist(). */
649 tvb_ensure_bytes_exist(tvb, offset, (int)length);
650}
651
652/* Validates that 'length' bytes are available starting from
653 * offset (pos/neg). Throws an exception if they aren't. */
654void
655tvb_ensure_bytes_exist(const tvbuff_t *tvb, const unsigned offset, const int length)
656{
657 unsigned end_offset;
658 int exception;
659
660 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 660, "tvb && tvb->initialized"
))))
;
661
662 /*
663 * -1 doesn't mean "until end of buffer", as that's pointless
664 * for this routine. We must treat it as a Really Large Positive
665 * Number, so that we throw an exception; we throw
666 * ReportedBoundsError, as if it were past even the end of a
667 * reassembled packet, and past the end of even the data we
668 * didn't capture.
669 *
670 * We do the same with other negative lengths.
671 */
672 if (length < 0) {
673 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
674 }
675
676 exception = validate_offset(tvb, offset);
677 if (exception)
678 THROW(exception)except_throw(1, (exception), ((void*)0));
679
680 /*
681 * Compute the offset of the first byte past the length.
682 */
683 end_offset = offset + length;
684
685 /*
686 * Check for an overflow
687 */
688 if (end_offset < offset)
689 THROW(BoundsError)except_throw(1, (1), ((void*)0));
690
691 if (G_LIKELY(end_offset <= tvb->length)(end_offset <= tvb->length))
692 return;
693 else if (end_offset <= tvb->contained_length)
694 THROW(BoundsError)except_throw(1, (1), ((void*)0));
695 else if (tvb->flags & TVBUFF_FRAGMENT0x00000001)
696 THROW(FragmentBoundsError)except_throw(1, (4), ((void*)0));
697 else if (end_offset <= tvb->reported_length)
698 THROW(ContainedBoundsError)except_throw(1, (2), ((void*)0));
699 else
700 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
701}
702
703bool_Bool
704tvb_offset_exists(const tvbuff_t *tvb, const int offset)
705{
706 unsigned abs_offset = 0;
707 int exception;
708
709 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 709, "tvb && tvb->initialized"
))))
;
710
711 exception = compute_offset(tvb, offset, &abs_offset);
712 if (exception)
713 return false0;
714
715 /* compute_offset only throws an exception on >, not >= because of the
716 * comment above check_offset_length_no_exception, but here we want the
717 * opposite behaviour so we check ourselves... */
718 return abs_offset < tvb->length;
719}
720
721unsigned
722tvb_reported_length(const tvbuff_t *tvb)
723{
724 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 724, "tvb && tvb->initialized"
))))
;
725
726 return tvb->reported_length;
727}
728
729int
730tvb_reported_length_remaining(const tvbuff_t *tvb, const int offset)
731{
732 unsigned abs_offset = 0;
733 int exception;
734
735 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 735, "tvb && tvb->initialized"
))))
;
736
737 exception = compute_offset(tvb, offset, &abs_offset);
738 if (exception)
739 return 0;
740
741 if (tvb->reported_length >= abs_offset)
742 return tvb->reported_length - abs_offset;
743 else
744 return 0;
745}
746
747unsigned
748tvb_ensure_reported_length_remaining(const tvbuff_t *tvb, const unsigned offset)
749{
750 int exception;
751
752 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 752, "tvb && tvb->initialized"
))))
;
753
754 exception = validate_offset(tvb, offset);
755 if (exception)
756 THROW(exception)except_throw(1, (exception), ((void*)0));
757
758 if (tvb->reported_length >= offset)
759 return tvb->reported_length - offset;
760 else
761 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
762}
763
764/* Set the reported length of a tvbuff to a given value; used for protocols
765 * whose headers contain an explicit length and where the calling
766 * dissector's payload may include padding as well as the packet for
767 * this protocol.
768 * Also adjusts the available and contained length. */
769void
770tvb_set_reported_length(tvbuff_t *tvb, const unsigned reported_length)
771{
772 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 772, "tvb && tvb->initialized"
))))
;
773
774 if (reported_length > tvb->reported_length)
775 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
776
777 tvb->reported_length = reported_length;
778 if (reported_length < tvb->length)
779 tvb->length = reported_length;
780 if (reported_length < tvb->contained_length)
781 tvb->contained_length = reported_length;
782}
783
784/* Repair a tvbuff where the captured length is greater than the
785 * reported length; such a tvbuff makes no sense, as it's impossible
786 * to capture more data than is in the packet.
787 */
788void
789tvb_fix_reported_length(tvbuff_t *tvb)
790{
791 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 791, "tvb && tvb->initialized"
))))
;
792 DISSECTOR_ASSERT(tvb->reported_length < tvb->length)((void) ((tvb->reported_length < tvb->length) ? (void
)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 792, "tvb->reported_length < tvb->length"
))))
;
793
794 tvb->reported_length = tvb->length;
795 if (tvb->contained_length < tvb->length)
796 tvb->contained_length = tvb->length;
797}
798
799unsigned
800tvb_offset_from_real_beginning_counter(const tvbuff_t *tvb, const unsigned counter)
801{
802 if (tvb->ops->tvb_offset)
803 return tvb->ops->tvb_offset(tvb, counter);
804
805 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/tvbuff.c", 805))
;
806 return 0;
807}
808
809unsigned
810tvb_offset_from_real_beginning(const tvbuff_t *tvb)
811{
812 return tvb_offset_from_real_beginning_counter(tvb, 0);
813}
814
815static inline const uint8_t*
816ensure_contiguous_no_exception(tvbuff_t *tvb, const int offset, const int length, int *pexception)
817{
818 unsigned abs_offset = 0, abs_length = 0;
819 int exception;
820
821 exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
822 if (exception) {
823 if (pexception)
824 *pexception = exception;
825 return NULL((void*)0);
826 }
827
828 /*
829 * Special case: if the caller (e.g. tvb_get_ptr) requested no data,
830 * then it is acceptable to have an empty tvb (!tvb->real_data).
831 */
832 if (length == 0) {
833 return NULL((void*)0);
834 }
835
836 /*
837 * We know that all the data is present in the tvbuff, so
838 * no exceptions should be thrown.
839 */
840 if (tvb->real_data)
841 return tvb->real_data + abs_offset;
842
843 if (tvb->ops->tvb_get_ptr)
844 return tvb->ops->tvb_get_ptr(tvb, abs_offset, abs_length);
845
846 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/tvbuff.c", 846))
;
847 return NULL((void*)0);
848}
849
850static inline const uint8_t*
851ensure_contiguous(tvbuff_t *tvb, const int offset, const int length)
852{
853 int exception = 0;
854 const uint8_t *p;
855
856 p = ensure_contiguous_no_exception(tvb, offset, length, &exception);
857 if (p == NULL((void*)0) && length != 0) {
858 DISSECTOR_ASSERT(exception > 0)((void) ((exception > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 858, "exception > 0"
))))
;
859 THROW(exception)except_throw(1, (exception), ((void*)0));
860 }
861 return p;
862}
863
864static inline const uint8_t*
865fast_ensure_contiguous(tvbuff_t *tvb, const int offset, const unsigned length)
866{
867 unsigned end_offset;
868 unsigned u_offset;
869
870 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 870, "tvb && tvb->initialized"
))))
;
871 /* We don't check for overflow in this fast path so we only handle simple types */
872 DISSECTOR_ASSERT(length <= 8)((void) ((length <= 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 872, "length <= 8"
))))
;
873
874 if (offset < 0 || !tvb->real_data) {
875 return ensure_contiguous(tvb, offset, length);
876 }
877
878 u_offset = offset;
879 end_offset = u_offset + length;
880
881 if (G_LIKELY(end_offset <= tvb->length)(end_offset <= tvb->length)) {
882 return tvb->real_data + u_offset;
883 } else if (end_offset <= tvb->contained_length) {
884 THROW(BoundsError)except_throw(1, (1), ((void*)0));
885 } else if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
886 THROW(FragmentBoundsError)except_throw(1, (4), ((void*)0));
887 } else if (end_offset <= tvb->reported_length) {
888 THROW(ContainedBoundsError)except_throw(1, (2), ((void*)0));
889 } else {
890 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
891 }
892 /* not reached */
893 return NULL((void*)0);
894}
895
896
897
898/************** ACCESSORS **************/
899
900void *
901tvb_memcpy(tvbuff_t *tvb, void *target, const int offset, size_t length)
902{
903 unsigned abs_offset = 0, abs_length = 0;
904
905 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 905, "tvb && tvb->initialized"
))))
;
906
907 /*
908 * XXX - we should eliminate the "length = -1 means 'to the end
909 * of the tvbuff'" convention, and use other means to achieve
910 * that; this would let us eliminate a bunch of checks for
911 * negative lengths in cases where the protocol has a 32-bit
912 * length field.
913 *
914 * Allowing -1 but throwing an assertion on other negative
915 * lengths is a bit more work with the length being a size_t;
916 * instead, we check for a length <= 2^31-1.
917 */
918 DISSECTOR_ASSERT(length <= 0x7FFFFFFF)((void) ((length <= 0x7FFFFFFF) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 918, "length <= 0x7FFFFFFF"
))))
;
919 check_offset_length(tvb, offset, (int) length, &abs_offset, &abs_length);
920
921 if (target && tvb->real_data) {
922 return memcpy(target, tvb->real_data + abs_offset, abs_length);
923 }
924
925 if (target && tvb->ops->tvb_memcpy)
926 return tvb->ops->tvb_memcpy(tvb, target, abs_offset, abs_length);
927
928 /*
929 * If the length is 0, there's nothing to do.
930 * (tvb->real_data could be null if it's allocated with
931 * a size of length.)
932 */
933 if (length != 0) {
934 /*
935 * XXX, fallback to slower method
936 */
937 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/tvbuff.c", 937))
;
938 }
939 return NULL((void*)0);
940}
941
942
943/*
944 * XXX - this doesn't treat a length of -1 as an error.
945 * If it did, this could replace some code that calls
946 * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies
947 * data to it.
948 *
949 * "composite_get_ptr()" depends on -1 not being
950 * an error; does anything else depend on this routine treating -1 as
951 * meaning "to the end of the buffer"?
952 *
953 * If scope is NULL, memory is allocated with g_malloc() and user must
954 * explicitly free it with g_free().
955 * If scope is not NULL, memory is allocated with the corresponding pool
956 * lifetime.
957 */
958void *
959tvb_memdup(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, size_t length)
960{
961 unsigned abs_offset = 0, abs_length = 0;
962 void *duped;
963
964 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 964, "tvb && tvb->initialized"
))))
;
965
966 check_offset_length(tvb, offset, (int) length, &abs_offset, &abs_length);
967
968 if (abs_length == 0)
969 return NULL((void*)0);
970
971 duped = wmem_alloc(scope, abs_length);
972 return tvb_memcpy(tvb, duped, abs_offset, abs_length);
973}
974
975
976
977const uint8_t*
978tvb_get_ptr(tvbuff_t *tvb, const int offset, const int length)
979{
980 return ensure_contiguous(tvb, offset, length);
981}
982
983/* ---------------- */
984uint8_t
985tvb_get_uint8(tvbuff_t *tvb, const int offset)
986{
987 const uint8_t *ptr;
988
989 ptr = fast_ensure_contiguous(tvb, offset, 1);
990 return *ptr;
991}
992
993int8_t
994tvb_get_int8(tvbuff_t *tvb, const int offset)
995{
996 const uint8_t *ptr;
997
998 ptr = fast_ensure_contiguous(tvb, offset, 1);
999 return *ptr;
1000}
1001
1002uint16_t
1003tvb_get_ntohs(tvbuff_t *tvb, const int offset)
1004{
1005 const uint8_t *ptr;
1006
1007 ptr = fast_ensure_contiguous(tvb, offset, 2);
1008 return pntohu16(ptr);
1009}
1010
1011int16_t
1012tvb_get_ntohis(tvbuff_t *tvb, const int offset)
1013{
1014 const uint8_t *ptr;
1015
1016 ptr = fast_ensure_contiguous(tvb, offset, 2);
1017 return pntohu16(ptr);
1018}
1019
1020uint32_t
1021tvb_get_ntoh24(tvbuff_t *tvb, const int offset)
1022{
1023 const uint8_t *ptr;
1024
1025 ptr = fast_ensure_contiguous(tvb, offset, 3);
1026 return pntohu24(ptr);
1027}
1028
1029int32_t
1030tvb_get_ntohi24(tvbuff_t *tvb, const int offset)
1031{
1032 uint32_t ret;
1033
1034 ret = ws_sign_ext32(tvb_get_ntoh24(tvb, offset), 24);
1035
1036 return (int32_t)ret;
1037}
1038
1039uint32_t
1040tvb_get_ntohl(tvbuff_t *tvb, const int offset)
1041{
1042 const uint8_t *ptr;
1043
1044 ptr = fast_ensure_contiguous(tvb, offset, 4);
1045 return pntohu32(ptr);
1046}
1047
1048int32_t
1049tvb_get_ntohil(tvbuff_t *tvb, const int offset)
1050{
1051 const uint8_t *ptr;
1052
1053 ptr = fast_ensure_contiguous(tvb, offset, 4);
1054 return pntohu32(ptr);
1055}
1056
1057uint64_t
1058tvb_get_ntoh40(tvbuff_t *tvb, const int offset)
1059{
1060 const uint8_t *ptr;
1061
1062 ptr = fast_ensure_contiguous(tvb, offset, 5);
1063 return pntohu40(ptr);
1064}
1065
1066int64_t
1067tvb_get_ntohi40(tvbuff_t *tvb, const int offset)
1068{
1069 uint64_t ret;
1070
1071 ret = ws_sign_ext64(tvb_get_ntoh40(tvb, offset), 40);
1072
1073 return (int64_t)ret;
1074}
1075
1076uint64_t
1077tvb_get_ntoh48(tvbuff_t *tvb, const int offset)
1078{
1079 const uint8_t *ptr;
1080
1081 ptr = fast_ensure_contiguous(tvb, offset, 6);
1082 return pntohu48(ptr);
1083}
1084
1085int64_t
1086tvb_get_ntohi48(tvbuff_t *tvb, const int offset)
1087{
1088 uint64_t ret;
1089
1090 ret = ws_sign_ext64(tvb_get_ntoh48(tvb, offset), 48);
1091
1092 return (int64_t)ret;
1093}
1094
1095uint64_t
1096tvb_get_ntoh56(tvbuff_t *tvb, const int offset)
1097{
1098 const uint8_t *ptr;
1099
1100 ptr = fast_ensure_contiguous(tvb, offset, 7);
1101 return pntohu56(ptr);
1102}
1103
1104int64_t
1105tvb_get_ntohi56(tvbuff_t *tvb, const int offset)
1106{
1107 uint64_t ret;
1108
1109 ret = ws_sign_ext64(tvb_get_ntoh56(tvb, offset), 56);
1110
1111 return (int64_t)ret;
1112}
1113
1114uint64_t
1115tvb_get_ntoh64(tvbuff_t *tvb, const int offset)
1116{
1117 const uint8_t *ptr;
1118
1119 ptr = fast_ensure_contiguous(tvb, offset, 8);
1120 return pntohu64(ptr);
1121}
1122
1123int64_t
1124tvb_get_ntohi64(tvbuff_t *tvb, const int offset)
1125{
1126 const uint8_t *ptr;
1127
1128 ptr = fast_ensure_contiguous(tvb, offset, 8);
1129 return pntohu64(ptr);
1130}
1131
1132uint16_t
1133tvb_get_uint16(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1134 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1135 return tvb_get_letohs(tvb, offset);
1136 } else {
1137 return tvb_get_ntohs(tvb, offset);
1138 }
1139}
1140
1141int16_t
1142tvb_get_int16(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1143 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1144 return tvb_get_letohis(tvb, offset);
1145 } else {
1146 return tvb_get_ntohis(tvb, offset);
1147 }
1148}
1149
1150uint32_t
1151tvb_get_uint24(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1152 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1153 return tvb_get_letoh24(tvb, offset);
1154 } else {
1155 return tvb_get_ntoh24(tvb, offset);
1156 }
1157}
1158
1159int32_t
1160tvb_get_int24(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1161 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1162 return tvb_get_letohi24(tvb, offset);
1163 } else {
1164 return tvb_get_ntohi24(tvb, offset);
1165 }
1166}
1167
1168uint32_t
1169tvb_get_uint32(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1170 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1171 return tvb_get_letohl(tvb, offset);
1172 } else {
1173 return tvb_get_ntohl(tvb, offset);
1174 }
1175}
1176
1177int32_t
1178tvb_get_int32(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1179 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1180 return tvb_get_letohil(tvb, offset);
1181 } else {
1182 return tvb_get_ntohil(tvb, offset);
1183 }
1184}
1185
1186uint64_t
1187tvb_get_uint40(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1188 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1189 return tvb_get_letoh40(tvb, offset);
1190 } else {
1191 return tvb_get_ntoh40(tvb, offset);
1192 }
1193}
1194
1195int64_t
1196tvb_get_int40(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1197 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1198 return tvb_get_letohi40(tvb, offset);
1199 } else {
1200 return tvb_get_ntohi40(tvb, offset);
1201 }
1202}
1203
1204uint64_t
1205tvb_get_uint48(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1206 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1207 return tvb_get_letoh48(tvb, offset);
1208 } else {
1209 return tvb_get_ntoh48(tvb, offset);
1210 }
1211}
1212
1213int64_t
1214tvb_get_int48(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1215 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1216 return tvb_get_letohi48(tvb, offset);
1217 } else {
1218 return tvb_get_ntohi48(tvb, offset);
1219 }
1220}
1221
1222uint64_t
1223tvb_get_uint56(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1224 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1225 return tvb_get_letoh56(tvb, offset);
1226 } else {
1227 return tvb_get_ntoh56(tvb, offset);
1228 }
1229}
1230
1231int64_t
1232tvb_get_int56(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1233 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1234 return tvb_get_letohi56(tvb, offset);
1235 } else {
1236 return tvb_get_ntohi56(tvb, offset);
1237 }
1238}
1239
1240uint64_t
1241tvb_get_uint64(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1242 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1243 return tvb_get_letoh64(tvb, offset);
1244 } else {
1245 return tvb_get_ntoh64(tvb, offset);
1246 }
1247}
1248
1249uint64_t
1250tvb_get_uint64_with_length(tvbuff_t *tvb, const int offset, unsigned length, const unsigned encoding)
1251{
1252 uint64_t value;
1253
1254 switch (length) {
1255
1256 case 1:
1257 value = tvb_get_uint8(tvb, offset);
1258 break;
1259
1260 case 2:
1261 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1262 : tvb_get_ntohs(tvb, offset);
1263 break;
1264
1265 case 3:
1266 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1267 : tvb_get_ntoh24(tvb, offset);
1268 break;
1269
1270 case 4:
1271 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1272 : tvb_get_ntohl(tvb, offset);
1273 break;
1274
1275 case 5:
1276 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh40(tvb, offset)
1277 : tvb_get_ntoh40(tvb, offset);
1278 break;
1279
1280 case 6:
1281 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh48(tvb, offset)
1282 : tvb_get_ntoh48(tvb, offset);
1283 break;
1284
1285 case 7:
1286 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh56(tvb, offset)
1287 : tvb_get_ntoh56(tvb, offset);
1288 break;
1289
1290 case 8:
1291 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh64(tvb, offset)
1292 : tvb_get_ntoh64(tvb, offset);
1293 break;
1294
1295 default:
1296 if (length < 1) {
1297 value = 0;
1298 } else {
1299 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh64(tvb, offset)
1300 : tvb_get_ntoh64(tvb, offset);
1301 }
1302 break;
1303 }
1304 return value;
1305}
1306
1307int64_t
1308tvb_get_int64(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1309 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1310 return tvb_get_letohi64(tvb, offset);
1311 } else {
1312 return tvb_get_ntohi64(tvb, offset);
1313 }
1314}
1315
1316float
1317tvb_get_ieee_float(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1318 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1319 return tvb_get_letohieee_float(tvb, offset);
1320 } else {
1321 return tvb_get_ntohieee_float(tvb, offset);
1322 }
1323}
1324
1325double
1326tvb_get_ieee_double(tvbuff_t *tvb, const int offset, const unsigned encoding) {
1327 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1328 return tvb_get_letohieee_double(tvb, offset);
1329 } else {
1330 return tvb_get_ntohieee_double(tvb, offset);
1331 }
1332}
1333
1334/*
1335 * Stuff for IEEE float handling on platforms that don't have IEEE
1336 * format as the native floating-point format.
1337 *
1338 * For now, we treat only the VAX as such a platform.
1339 *
1340 * XXX - other non-IEEE boxes that can run UN*X include some Crays,
1341 * and possibly other machines. However, I don't know whether there
1342 * are any other machines that could run Wireshark and that don't use
1343 * IEEE format. As far as I know, all of the main current and past
1344 * commercial microprocessor families on which OSes that support
1345 * Wireshark can run use IEEE format (x86, ARM, 68k, SPARC, MIPS,
1346 * PA-RISC, Alpha, IA-64, and so on), and it appears that the official
1347 * Linux port to System/390 and zArchitecture uses IEEE format floating-
1348 * point rather than IBM hex floating-point (not a huge surprise), so
1349 * I'm not sure that leaves any 32-bit or larger UN*X or Windows boxes,
1350 * other than VAXes, that don't use IEEE format. If you're not running
1351 * UN*X or Windows, the floating-point format is probably going to be
1352 * the least of your problems in a port.
1353 */
1354
1355#if defined(vax)
1356
1357#include <math.h>
1358
1359/*
1360 * Single-precision.
1361 */
1362#define IEEE_SP_NUMBER_WIDTH 32 /* bits in number */
1363#define IEEE_SP_EXP_WIDTH 8 /* bits in exponent */
1364#define IEEE_SP_MANTISSA_WIDTH 23 /* IEEE_SP_NUMBER_WIDTH - 1 - IEEE_SP_EXP_WIDTH */
1365
1366#define IEEE_SP_SIGN_MASK 0x80000000
1367#define IEEE_SP_EXPONENT_MASK 0x7F800000
1368#define IEEE_SP_MANTISSA_MASK 0x007FFFFF
1369#define IEEE_SP_INFINITY IEEE_SP_EXPONENT_MASK
1370
1371#define IEEE_SP_IMPLIED_BIT (1 << IEEE_SP_MANTISSA_WIDTH)
1372#define IEEE_SP_INFINITE ((1 << IEEE_SP_EXP_WIDTH) - 1)
1373#define IEEE_SP_BIAS ((1 << (IEEE_SP_EXP_WIDTH - 1)) - 1)
1374
1375static int
1376ieee_float_is_zero(const uint32_t w)
1377{
1378 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1379}
1380
1381static float
1382get_ieee_float(const uint32_t w)
1383{
1384 long sign;
1385 long exponent;
1386 long mantissa;
1387
1388 sign = w & IEEE_SP_SIGN_MASK;
1389 exponent = w & IEEE_SP_EXPONENT_MASK;
1390 mantissa = w & IEEE_SP_MANTISSA_MASK;
1391
1392 if (ieee_float_is_zero(w)) {
1393 /* number is zero, unnormalized, or not-a-number */
1394 return 0.0;
1395 }
1396#if 0
1397 /*
1398 * XXX - how to handle this?
1399 */
1400 if (IEEE_SP_INFINITY == exponent) {
1401 /*
1402 * number is positive or negative infinity, or a special value
1403 */
1404 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1405 }
1406#endif
1407
1408 exponent = ((exponent >> IEEE_SP_MANTISSA_WIDTH) - IEEE_SP_BIAS) -
1409 IEEE_SP_MANTISSA_WIDTH;
1410 mantissa |= IEEE_SP_IMPLIED_BIT;
1411
1412 if (sign)
1413 return -mantissa * pow(2, exponent);
1414 else
1415 return mantissa * pow(2, exponent);
1416}
1417
1418/*
1419 * Double-precision.
1420 * We assume that if you don't have IEEE floating-point, you have a
1421 * compiler that understands 64-bit integral quantities.
1422 */
1423#define IEEE_DP_NUMBER_WIDTH 64 /* bits in number */
1424#define IEEE_DP_EXP_WIDTH 11 /* bits in exponent */
1425#define IEEE_DP_MANTISSA_WIDTH 52 /* IEEE_DP_NUMBER_WIDTH - 1 - IEEE_DP_EXP_WIDTH */
1426
1427#define IEEE_DP_SIGN_MASK INT64_C(0x8000000000000000)0x8000000000000000L
1428#define IEEE_DP_EXPONENT_MASK INT64_C(0x7FF0000000000000)0x7FF0000000000000L
1429#define IEEE_DP_MANTISSA_MASK INT64_C(0x000FFFFFFFFFFFFF)0x000FFFFFFFFFFFFFL
1430#define IEEE_DP_INFINITY IEEE_DP_EXPONENT_MASK
1431
1432#define IEEE_DP_IMPLIED_BIT (INT64_C(1)1L << IEEE_DP_MANTISSA_WIDTH)
1433#define IEEE_DP_INFINITE ((1 << IEEE_DP_EXP_WIDTH) - 1)
1434#define IEEE_DP_BIAS ((1 << (IEEE_DP_EXP_WIDTH - 1)) - 1)
1435
1436static int
1437ieee_double_is_zero(const uint64_t w)
1438{
1439 return ((w & ~IEEE_SP_SIGN_MASK) == 0);
1440}
1441
1442static double
1443get_ieee_double(const uint64_t w)
1444{
1445 int64_t sign;
1446 int64_t exponent;
1447 int64_t mantissa;
1448
1449 sign = w & IEEE_DP_SIGN_MASK;
1450 exponent = w & IEEE_DP_EXPONENT_MASK;
1451 mantissa = w & IEEE_DP_MANTISSA_MASK;
1452
1453 if (ieee_double_is_zero(w)) {
1454 /* number is zero, unnormalized, or not-a-number */
1455 return 0.0;
1456 }
1457#if 0
1458 /*
1459 * XXX - how to handle this?
1460 */
1461 if (IEEE_DP_INFINITY == exponent) {
1462 /*
1463 * number is positive or negative infinity, or a special value
1464 */
1465 return (sign? MINUS_INFINITY: PLUS_INFINITY);
1466 }
1467#endif
1468
1469 exponent = ((exponent >> IEEE_DP_MANTISSA_WIDTH) - IEEE_DP_BIAS) -
1470 IEEE_DP_MANTISSA_WIDTH;
1471 mantissa |= IEEE_DP_IMPLIED_BIT;
1472
1473 if (sign)
1474 return -mantissa * pow(2, exponent);
1475 else
1476 return mantissa * pow(2, exponent);
1477}
1478#endif
1479
1480/*
1481 * Fetches an IEEE single-precision floating-point number, in
1482 * big-endian form, and returns a "float".
1483 *
1484 * XXX - should this be "double", in case there are IEEE single-
1485 * precision numbers that won't fit in some platform's native
1486 * "float" format?
1487 */
1488float
1489tvb_get_ntohieee_float(tvbuff_t *tvb, const int offset)
1490{
1491#if defined(vax)
1492 return get_ieee_float(tvb_get_ntohl(tvb, offset));
1493#else
1494 union {
1495 float f;
1496 uint32_t w;
1497 } ieee_fp_union;
1498
1499 ieee_fp_union.w = tvb_get_ntohl(tvb, offset);
1500 return ieee_fp_union.f;
1501#endif
1502}
1503
1504/*
1505 * Fetches an IEEE double-precision floating-point number, in
1506 * big-endian form, and returns a "double".
1507 */
1508double
1509tvb_get_ntohieee_double(tvbuff_t *tvb, const int offset)
1510{
1511#if defined(vax)
1512 union {
1513 uint32_t w[2];
1514 uint64_t dw;
1515 } ieee_fp_union;
1516#else
1517 union {
1518 double d;
1519 uint32_t w[2];
1520 } ieee_fp_union;
1521#endif
1522
1523#if G_BYTE_ORDER1234 == G_BIG_ENDIAN4321
1524 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset);
1525 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset+4);
1526#else
1527 ieee_fp_union.w[0] = tvb_get_ntohl(tvb, offset+4);
1528 ieee_fp_union.w[1] = tvb_get_ntohl(tvb, offset);
1529#endif
1530#if defined(vax)
1531 return get_ieee_double(ieee_fp_union.dw);
1532#else
1533 return ieee_fp_union.d;
1534#endif
1535}
1536
1537uint16_t
1538tvb_get_letohs(tvbuff_t *tvb, const int offset)
1539{
1540 const uint8_t *ptr;
1541
1542 ptr = fast_ensure_contiguous(tvb, offset, 2);
1543 return pletohu16(ptr);
1544}
1545
1546int16_t
1547tvb_get_letohis(tvbuff_t *tvb, const int offset)
1548{
1549 const uint8_t *ptr;
1550
1551 ptr = fast_ensure_contiguous(tvb, offset, 2);
1552 return pletohu16(ptr);
1553}
1554
1555uint32_t
1556tvb_get_letoh24(tvbuff_t *tvb, const int offset)
1557{
1558 const uint8_t *ptr;
1559
1560 ptr = fast_ensure_contiguous(tvb, offset, 3);
1561 return pletohu24(ptr);
1562}
1563
1564int32_t
1565tvb_get_letohi24(tvbuff_t *tvb, const int offset)
1566{
1567 uint32_t ret;
1568
1569 ret = ws_sign_ext32(tvb_get_letoh24(tvb, offset), 24);
1570
1571 return (int32_t)ret;
1572}
1573
1574uint32_t
1575tvb_get_letohl(tvbuff_t *tvb, const int offset)
1576{
1577 const uint8_t *ptr;
1578
1579 ptr = fast_ensure_contiguous(tvb, offset, 4);
1580 return pletohu32(ptr);
1581}
1582
1583int32_t
1584tvb_get_letohil(tvbuff_t *tvb, const int offset)
1585{
1586 const uint8_t *ptr;
1587
1588 ptr = fast_ensure_contiguous(tvb, offset, 4);
1589 return pletohu32(ptr);
1590}
1591
1592uint64_t
1593tvb_get_letoh40(tvbuff_t *tvb, const int offset)
1594{
1595 const uint8_t *ptr;
1596
1597 ptr = fast_ensure_contiguous(tvb, offset, 5);
1598 return pletohu40(ptr);
1599}
1600
1601int64_t
1602tvb_get_letohi40(tvbuff_t *tvb, const int offset)
1603{
1604 uint64_t ret;
1605
1606 ret = ws_sign_ext64(tvb_get_letoh40(tvb, offset), 40);
1607
1608 return (int64_t)ret;
1609}
1610
1611uint64_t
1612tvb_get_letoh48(tvbuff_t *tvb, const int offset)
1613{
1614 const uint8_t *ptr;
1615
1616 ptr = fast_ensure_contiguous(tvb, offset, 6);
1617 return pletohu48(ptr);
1618}
1619
1620int64_t
1621tvb_get_letohi48(tvbuff_t *tvb, const int offset)
1622{
1623 uint64_t ret;
1624
1625 ret = ws_sign_ext64(tvb_get_letoh48(tvb, offset), 48);
1626
1627 return (int64_t)ret;
1628}
1629
1630uint64_t
1631tvb_get_letoh56(tvbuff_t *tvb, const int offset)
1632{
1633 const uint8_t *ptr;
1634
1635 ptr = fast_ensure_contiguous(tvb, offset, 7);
1636 return pletohu56(ptr);
1637}
1638
1639int64_t
1640tvb_get_letohi56(tvbuff_t *tvb, const int offset)
1641{
1642 uint64_t ret;
1643
1644 ret = ws_sign_ext64(tvb_get_letoh56(tvb, offset), 56);
1645
1646 return (int64_t)ret;
1647}
1648
1649uint64_t
1650tvb_get_letoh64(tvbuff_t *tvb, const int offset)
1651{
1652 const uint8_t *ptr;
1653
1654 ptr = fast_ensure_contiguous(tvb, offset, 8);
1655 return pletohu64(ptr);
1656}
1657
1658int64_t
1659tvb_get_letohi64(tvbuff_t *tvb, const int offset)
1660{
1661 const uint8_t *ptr;
1662
1663 ptr = fast_ensure_contiguous(tvb, offset, 8);
1664 return pletohu64(ptr);
1665}
1666
1667/*
1668 * Fetches an IEEE single-precision floating-point number, in
1669 * little-endian form, and returns a "float".
1670 *
1671 * XXX - should this be "double", in case there are IEEE single-
1672 * precision numbers that won't fit in some platform's native
1673 * "float" format?
1674 */
1675float
1676tvb_get_letohieee_float(tvbuff_t *tvb, const int offset)
1677{
1678#if defined(vax)
1679 return get_ieee_float(tvb_get_letohl(tvb, offset));
1680#else
1681 union {
1682 float f;
1683 uint32_t w;
1684 } ieee_fp_union;
1685
1686 ieee_fp_union.w = tvb_get_letohl(tvb, offset);
1687 return ieee_fp_union.f;
1688#endif
1689}
1690
1691/*
1692 * Fetches an IEEE double-precision floating-point number, in
1693 * little-endian form, and returns a "double".
1694 */
1695double
1696tvb_get_letohieee_double(tvbuff_t *tvb, const int offset)
1697{
1698#if defined(vax)
1699 union {
1700 uint32_t w[2];
1701 uint64_t dw;
1702 } ieee_fp_union;
1703#else
1704 union {
1705 double d;
1706 uint32_t w[2];
1707 } ieee_fp_union;
1708#endif
1709
1710#if G_BYTE_ORDER1234 == G_BIG_ENDIAN4321
1711 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset+4);
1712 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset);
1713#else
1714 ieee_fp_union.w[0] = tvb_get_letohl(tvb, offset);
1715 ieee_fp_union.w[1] = tvb_get_letohl(tvb, offset+4);
1716#endif
1717#if defined(vax)
1718 return get_ieee_double(ieee_fp_union.dw);
1719#else
1720 return ieee_fp_union.d;
1721#endif
1722}
1723
1724/* This function is a slight misnomer. It accepts all encodings that are
1725 * ASCII "enough", which means encodings that are the same as US-ASCII
1726 * for textual representations of dates and hex bytes; i.e., the same
1727 * for the hex digits and Z (in practice, all alphanumerics), and the
1728 * four separators ':' '-' '.' and ' '
1729 * That means that any encoding that keeps the ISO/IEC 646 invariant
1730 * characters the same (including the T.61 8 bit encoding and multibyte
1731 * encodings like EUC-KR and GB18030) are OK, even if they replace characters
1732 * like '$' '#' and '\' with national variants, but not encodings like UTF-16
1733 * that include extra null bytes.
1734 * For our current purposes, the unpacked GSM 7-bit default alphabet (but not
1735 * all National Language Shift Tables) also satisfies this requirement, but
1736 * note that it does *not* keep all ISO/IEC 646 invariant characters the same.
1737 * If this internal function gets used for additional purposes than currently,
1738 * the set of encodings that it accepts could change.
1739 * */
1740static inline void
1741validate_single_byte_ascii_encoding(const unsigned encoding)
1742{
1743 const unsigned enc = encoding & ~ENC_CHARENCODING_MASK0x0000FFFE;
1744
1745 switch (enc) {
1746 case ENC_UTF_160x00000004:
1747 case ENC_UCS_20x00000006:
1748 case ENC_UCS_40x00000008:
1749 case ENC_3GPP_TS_23_038_7BITS_PACKED0x0000002C:
1750 case ENC_ASCII_7BITS0x00000034:
1751 case ENC_EBCDIC0x0000002E:
1752 case ENC_EBCDIC_CP0370x00000038:
1753 case ENC_EBCDIC_CP5000x00000060:
1754 case ENC_BCD_DIGITS_0_90x00000044:
1755 case ENC_KEYPAD_ABC_TBCD0x00000046:
1756 case ENC_KEYPAD_BC_TBCD0x00000048:
1757 case ENC_ETSI_TS_102_221_ANNEX_A0x0000004E:
1758 case ENC_APN_STR0x00000054:
1759 case ENC_DECT_STANDARD_4BITS_TBCD0x00000058:
1760 REPORT_DISSECTOR_BUG("Invalid string encoding type passed to tvb_get_string_XXX")proto_report_dissector_bug("Invalid string encoding type passed to tvb_get_string_XXX"
)
;
1761 break;
1762 default:
1763 break;
1764 }
1765 /* make sure something valid was set */
1766 if (enc == 0)
1767 REPORT_DISSECTOR_BUG("No string encoding type passed to tvb_get_string_XXX")proto_report_dissector_bug("No string encoding type passed to tvb_get_string_XXX"
)
;
1768}
1769
1770GByteArray*
1771tvb_get_string_bytes(tvbuff_t *tvb, const int offset, const int length,
1772 const unsigned encoding, GByteArray *bytes, int *endoff)
1773{
1774 char *ptr;
1775 const char *begin;
1776 const char *end = NULL((void*)0);
1777 GByteArray *retval = NULL((void*)0);
1778
1779 validate_single_byte_ascii_encoding(encoding);
1780
1781 ptr = (char*) tvb_get_raw_string(NULL((void*)0), tvb, offset, length);
1782 begin = ptr;
1783
1784 if (endoff) *endoff = offset;
1785
1786 while (*begin == ' ') begin++;
1787
1788 if (*begin && bytes) {
1789 if (hex_str_to_bytes_encoding(begin, bytes, &end, encoding, false0)) {
1790 if (bytes->len > 0) {
1791 if (endoff) *endoff = offset + (int)(end - ptr);
1792 retval = bytes;
1793 }
1794 }
1795 }
1796
1797 wmem_free(NULL((void*)0), ptr);
1798
1799 return retval;
1800}
1801
1802static bool_Bool
1803parse_month_name(const char *name, int *tm_mon)
1804{
1805 static const char months[][4] = { "Jan", "Feb", "Mar", "Apr", "May",
1806 "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
1807 for (int i = 0; i < 12; i++) {
1808 if (memcmp(months[i], name, 4) == 0) {
1809 *tm_mon = i;
1810 return true1;
1811 }
1812 }
1813 return false0;
1814}
1815
1816/*
1817 * Is the character a WSP character, as per RFC 5234? (space or tab).
1818 */
1819#define IS_WSP(c)((c) == ' ' || (c) == '\t') ((c) == ' ' || (c) == '\t')
1820
1821/* support hex-encoded time values? */
1822nstime_t*
1823tvb_get_string_time(tvbuff_t *tvb, const int offset, const int length,
1824 const unsigned encoding, nstime_t *ns, int *endoff)
1825{
1826 char *begin;
1827 const char *ptr;
1828 const char *end = NULL((void*)0);
1829 int num_chars = 0;
1830 int utc_offset = 0;
1831
1832 validate_single_byte_ascii_encoding(encoding);
1833
1834 DISSECTOR_ASSERT(ns)((void) ((ns) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 1834, "ns"))))
;
1835
1836 begin = (char*) tvb_get_raw_string(NULL((void*)0), tvb, offset, length);
1837 ptr = begin;
1838
1839 while (IS_WSP(*ptr)((*ptr) == ' ' || (*ptr) == '\t'))
1840 ptr++;
1841
1842 if (*ptr) {
1843 if ((encoding & ENC_ISO_8601_DATE_TIME0x00030000) == ENC_ISO_8601_DATE_TIME0x00030000) {
1844 if (!(end = iso8601_to_nstime(ns, ptr, ISO8601_DATETIME))) {
1845
1846
1847 goto fail;
1848 }
1849 } else if ((encoding & ENC_ISO_8601_DATE_TIME_BASIC0x00100000) == ENC_ISO_8601_DATE_TIME_BASIC0x00100000) {
1850 if (!(end = iso8601_to_nstime(ns, ptr, ISO8601_DATETIME_BASIC))) {
1851
1852
1853 goto fail;
1854 }
1855 } else {
1856 struct tm tm;
1857
1858 memset(&tm, 0, sizeof(tm));
1859 tm.tm_isdst = -1;
1860 ns->secs = 0;
1861 ns->nsecs = 0;
1862
1863 /* note: sscanf is known to be inconsistent across platforms with respect
1864 to whether a %n is counted as a return value or not, so we have to use
1865 '>=' a lot */
1866 if (encoding & ENC_ISO_8601_DATE0x00010000) {
1867 /* 2014-04-07 */
1868 if (sscanf(ptr, "%d-%d-%d%n",
1869 &tm.tm_year,
1870 &tm.tm_mon,
1871 &tm.tm_mday,
1872 &num_chars) >= 3)
1873 {
1874 end = ptr + num_chars;
1875 tm.tm_mon--;
1876 if (tm.tm_year > 1900) tm.tm_year -= 1900;
1877 } else {
1878 goto fail;
1879 }
1880 }
1881 else if (encoding & ENC_ISO_8601_TIME0x00020000) {
1882 /* 2014-04-07 */
1883 if (sscanf(ptr, "%d:%d:%d%n",
1884 &tm.tm_hour,
1885 &tm.tm_min,
1886 &tm.tm_sec,
1887 &num_chars) >= 2)
1888 {
1889 /* what should we do about day/month/year? */
1890 /* setting it to "now" for now */
1891 time_t time_now = time(NULL((void*)0));
1892 struct tm *tm_now = gmtime(&time_now);
1893 if (tm_now != NULL((void*)0)) {
1894 tm.tm_year = tm_now->tm_year;
1895 tm.tm_mon = tm_now->tm_mon;
1896 tm.tm_mday = tm_now->tm_mday;
1897 } else {
1898 /* The second before the Epoch */
1899 tm.tm_year = 69;
1900 tm.tm_mon = 12;
1901 tm.tm_mday = 31;
1902 }
1903 end = ptr + num_chars;
1904 } else {
1905 goto fail;
1906 }
1907 }
1908 else if (encoding & ENC_IMF_DATE_TIME0x00040000) {
1909 /*
1910 * Match [dow,] day month year hh:mm[:ss] with
1911 * two-digit years (RFC 822) or four-digit
1912 * years (RFCs 1123, 2822, 5822). Skip
1913 * the day of week since it is locale
1914 * dependent and does not affect the resulting
1915 * date anyway.
1916 */
1917 if (g_ascii_isalpha(ptr[0])((g_ascii_table[(guchar) (ptr[0])] & G_ASCII_ALPHA) != 0) && g_ascii_isalpha(ptr[1])((g_ascii_table[(guchar) (ptr[1])] & G_ASCII_ALPHA) != 0) && g_ascii_isalpha(ptr[2])((g_ascii_table[(guchar) (ptr[2])] & G_ASCII_ALPHA) != 0) && ptr[3] == ',')
1918 ptr += 4; /* Skip day of week. */
1919
1920 /*
1921 * Parse the day-of-month and month
1922 * name.
1923 */
1924 char month_name[4] = { 0 };
1925
1926 if (sscanf(ptr, "%d %3s%n",
1927 &tm.tm_mday,
1928 month_name,
1929 &num_chars) < 2)
1930 {
1931 /* Not matched. */
1932 goto fail;
1933 }
1934 if (!parse_month_name(month_name, &tm.tm_mon)) {
1935 goto fail;
1936 }
1937 ptr += num_chars;
1938 while (IS_WSP(*ptr)((*ptr) == ' ' || (*ptr) == '\t'))
1939 ptr++;
1940
1941 /*
1942 * Scan the year. Treat 2-digit years
1943 * differently from 4-digit years.
1944 */
1945 uint32_t year;
1946 const char *yearendp;
1947
1948 if (!ws_strtou32(ptr, &yearendp, &year)) {
1949 goto fail;
1950 }
1951 if (!IS_WSP(*yearendp)((*yearendp) == ' ' || (*yearendp) == '\t')) {
1952 /* Not followed by WSP. */
1953 goto fail;
1954 }
1955 if (yearendp - ptr < 2) {
1956 /* 1-digit year. Error. */
1957 goto fail;
1958 }
1959 if (yearendp - ptr == 2) {
1960 /*
1961 * 2-digit year.
1962 *
1963 * Match RFC 2822/RFC 5322 behavior;
1964 * add 2000 to years from 0 to
1965 * 49 and 1900 to uears from 50
1966 * to 99.
1967 */
1968 if (year <= 49) {
1969 year += 2000;
1970 } else {
1971 year += 1900;
1972 }
1973 } else if (yearendp - ptr == 3) {
1974 /*
1975 * 3-digit year.
1976 *
1977 * Match RFC 2822/RFC 5322 behavior;
1978 * add 1900 to the year.
1979 */
1980 year += 1900;
1981 }
1982 tm.tm_year = year - 1900;
1983 ptr = yearendp;
1984 while (IS_WSP(*ptr)((*ptr) == ' ' || (*ptr) == '\t'))
1985 ptr++;
1986
1987 /* Parse the time. */
1988 if (sscanf(ptr, "%d:%d%n:%d%n",
1989 &tm.tm_hour,
1990 &tm.tm_min,
1991 &num_chars,
1992 &tm.tm_sec,
1993 &num_chars) < 2)
1994 {
1995 goto fail;
1996 }
1997 ptr += num_chars;
1998 while (IS_WSP(*ptr)((*ptr) == ' ' || (*ptr) == '\t'))
1999 ptr++;
2000
2001 /*
2002 * Parse the time zone.
2003 * Check for obs-zone values first.
2004 */
2005 if (g_ascii_strncasecmp(ptr, "UT", 2) == 0)
2006 {
2007 ptr += 2;
2008 }
2009 else if (g_ascii_strncasecmp(ptr, "GMT", 3) == 0)
2010 {
2011 ptr += 3;
2012 }
2013 else
2014 {
2015 char sign;
2016 int off_hr;
2017 int off_min;
2018
2019 if (sscanf(ptr, "%c%2d%2d%n",
2020 &sign,
2021 &off_hr,
2022 &off_min,
2023 &num_chars) < 3)
2024 {
2025 goto fail;
2026 }
2027
2028 /*
2029 * If sign is '+', there's a positive
2030 * UTC offset.
2031 *
2032 * If sign is '-', there's a negative
2033 * UTC offset.
2034 *
2035 * Otherwise, that's an invalid UTC
2036 * offset string.
2037 */
2038 if (sign == '+')
2039 utc_offset += (off_hr * 3600) + (off_min * 60);
2040 else if (sign == '-')
2041 utc_offset -= (off_hr * 3600) + (off_min * 60);
2042 else {
2043 /* Sign must be + or - */
2044 goto fail;
2045 }
2046 ptr += num_chars;
2047 }
2048 end = ptr;
2049 }
2050 ns->secs = mktime_utc(&tm);
2051 if (ns->secs == (time_t)-1 && errno(*__errno_location ()) != 0) {
2052 goto fail;
2053 }
2054 ns->secs += utc_offset;
2055 }
2056 } else {
2057 /* Empty string */
2058 goto fail;
2059 }
2060
2061 if (endoff)
2062 *endoff = (int)(offset + (end - begin));
2063 wmem_free(NULL((void*)0), begin);
2064 return ns;
2065
2066fail:
2067 wmem_free(NULL((void*)0), begin);
2068 return NULL((void*)0);
2069}
2070
2071/* Fetch an IPv4 address, in network byte order.
2072 * We do *not* convert them to host byte order; we leave them in
2073 * network byte order. */
2074uint32_t
2075tvb_get_ipv4(tvbuff_t *tvb, const int offset)
2076{
2077 const uint8_t *ptr;
2078 uint32_t addr;
2079
2080 ptr = fast_ensure_contiguous(tvb, offset, sizeof(uint32_t));
2081 memcpy(&addr, ptr, sizeof addr);
2082 return addr;
2083}
2084
2085/* Fetch an IPv6 address. */
2086void
2087tvb_get_ipv6(tvbuff_t *tvb, const int offset, ws_in6_addr *addr)
2088{
2089 const uint8_t *ptr;
2090
2091 ptr = ensure_contiguous(tvb, offset, sizeof(*addr));
2092 memcpy(addr, ptr, sizeof *addr);
2093}
2094
2095/*
2096 * These routines return the length of the address in bytes on success
2097 * and -1 if the prefix length is too long.
2098 */
2099int
2100tvb_get_ipv4_addr_with_prefix_len(tvbuff_t *tvb, int offset, ws_in4_addr *addr,
2101 uint32_t prefix_len)
2102{
2103 uint8_t addr_len;
2104
2105 if (prefix_len > 32)
2106 return -1;
2107
2108 addr_len = (prefix_len + 7) / 8;
2109 *addr = 0;
2110 tvb_memcpy(tvb, addr, offset, addr_len);
2111 if (prefix_len % 8)
2112 ((uint8_t*)addr)[addr_len - 1] &= ((0xff00 >> (prefix_len % 8)) & 0xff);
2113 return addr_len;
2114}
2115
2116/*
2117 * These routines return the length of the address in bytes on success
2118 * and -1 if the prefix length is too long.
2119 */
2120int
2121tvb_get_ipv6_addr_with_prefix_len(tvbuff_t *tvb, int offset, ws_in6_addr *addr,
2122 uint32_t prefix_len)
2123{
2124 uint32_t addr_len;
2125
2126 if (prefix_len > 128)
2127 return -1;
2128
2129 addr_len = (prefix_len + 7) / 8;
2130 memset(addr->bytes, 0, 16);
2131 tvb_memcpy(tvb, addr->bytes, offset, addr_len);
2132 if (prefix_len % 8) {
2133 addr->bytes[addr_len - 1] &=
2134 ((0xff00 >> (prefix_len % 8)) & 0xff);
2135 }
2136
2137 return addr_len;
2138}
2139
2140/* Fetch a GUID. */
2141void
2142tvb_get_ntohguid(tvbuff_t *tvb, const int offset, e_guid_t *guid)
2143{
2144 const uint8_t *ptr = ensure_contiguous(tvb, offset, GUID_LEN16);
2145
2146 guid->data1 = pntohu32(ptr + 0);
2147 guid->data2 = pntohu16(ptr + 4);
2148 guid->data3 = pntohu16(ptr + 6);
2149 memcpy(guid->data4, ptr + 8, sizeof guid->data4);
2150}
2151
2152void
2153tvb_get_letohguid(tvbuff_t *tvb, const int offset, e_guid_t *guid)
2154{
2155 const uint8_t *ptr = ensure_contiguous(tvb, offset, GUID_LEN16);
2156
2157 guid->data1 = pletohu32(ptr + 0);
2158 guid->data2 = pletohu16(ptr + 4);
2159 guid->data3 = pletohu16(ptr + 6);
2160 memcpy(guid->data4, ptr + 8, sizeof guid->data4);
2161}
2162
2163void
2164tvb_get_guid(tvbuff_t *tvb, const int offset, e_guid_t *guid, const unsigned encoding)
2165{
2166 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
2167 tvb_get_letohguid(tvb, offset, guid);
2168 } else {
2169 tvb_get_ntohguid(tvb, offset, guid);
2170 }
2171}
2172
2173static const uint8_t bit_mask8[] = {
2174 0x00,
2175 0x01,
2176 0x03,
2177 0x07,
2178 0x0f,
2179 0x1f,
2180 0x3f,
2181 0x7f,
2182 0xff
2183};
2184
2185
2186/* Get a variable amount of bits
2187 *
2188 * Return a byte array with bit limited data.
2189 * When encoding is ENC_BIG_ENDIAN, the data is aligned to the left.
2190 * When encoding is ENC_LITTLE_ENDIAN, the data is aligned to the right.
2191 */
2192uint8_t *
2193tvb_get_bits_array(wmem_allocator_t *scope, tvbuff_t *tvb, const int bit_offset,
2194 size_t no_of_bits, size_t *data_length, const unsigned encoding)
2195{
2196 tvbuff_t *sub_tvb;
2197 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
1
Assuming the condition is false
2
Taking false branch
2198 sub_tvb = tvb_new_octet_right_aligned(tvb, bit_offset, (int32_t) no_of_bits);
2199 } else {
2200 sub_tvb = tvb_new_octet_aligned(tvb, bit_offset, (int32_t) no_of_bits);
3
Calling 'tvb_new_octet_aligned'
2201 }
2202 *data_length = tvb_reported_length(sub_tvb);
2203 return (uint8_t*)tvb_memdup(scope, sub_tvb, 0, *data_length);
2204}
2205
2206/* Get 1 - 8 bits */
2207uint8_t
2208tvb_get_bits8(tvbuff_t *tvb, unsigned bit_offset, const int no_of_bits)
2209{
2210 DISSECTOR_ASSERT_HINT(no_of_bits <= 8, "Too many bits requested for 8-bit return type")((void) ((no_of_bits <= 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/tvbuff.c", 2210
, "no_of_bits <= 8", "Too many bits requested for 8-bit return type"
))))
;
2211 return (uint8_t)_tvb_get_bits64(tvb, bit_offset, no_of_bits);
2212}
2213
2214/* Get 1 - 16 bits */
2215uint16_t
2216tvb_get_bits16(tvbuff_t *tvb, unsigned bit_offset, const int no_of_bits, const unsigned encoding)
2217{
2218 DISSECTOR_ASSERT_HINT(no_of_bits <= 16, "Too many bits requested for 16-bit return type")((void) ((no_of_bits <= 16) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/tvbuff.c", 2218
, "no_of_bits <= 16", "Too many bits requested for 16-bit return type"
))))
;
2219 return (uint16_t)tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
2220}
2221
2222/* Get 1 - 32 bits */
2223uint32_t
2224tvb_get_bits32(tvbuff_t *tvb, unsigned bit_offset, const int no_of_bits, const unsigned encoding)
2225{
2226 DISSECTOR_ASSERT_HINT(no_of_bits <= 32, "Too many bits requested for 32-bit return type")((void) ((no_of_bits <= 32) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/tvbuff.c", 2226
, "no_of_bits <= 32", "Too many bits requested for 32-bit return type"
))))
;
2227 return (uint32_t)tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
2228}
2229
2230/* Get 1 - 64 bits */
2231uint64_t
2232tvb_get_bits64(tvbuff_t *tvb, unsigned bit_offset, const int no_of_bits, const unsigned encoding)
2233{
2234 DISSECTOR_ASSERT_HINT(no_of_bits <= 64, "Too many bits requested for 64-bit return type")((void) ((no_of_bits <= 64) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/tvbuff.c", 2234
, "no_of_bits <= 64", "Too many bits requested for 64-bit return type"
))))
;
2235
2236 /* encoding determines bit numbering within octet array */
2237 if (encoding & ENC_LITTLE_ENDIAN0x80000000) {
2238 return _tvb_get_bits64_le(tvb, bit_offset, no_of_bits);
2239 } else {
2240 return _tvb_get_bits64(tvb, bit_offset, no_of_bits);
2241 }
2242}
2243
2244/*
2245 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
2246 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
2247 * Offset should be given in bits from the start of the tvb.
2248 * Bits within octet are numbered from MSB (0) to LSB (7). Bit at bit_offset is return value most significant bit.
2249 * The function tolerates requests for more than 64 bits, but will only return the least significant 64 bits.
2250 */
2251static uint64_t
2252_tvb_get_bits64(tvbuff_t *tvb, unsigned bit_offset, const int total_no_of_bits)
2253{
2254 uint64_t value;
2255 unsigned octet_offset = bit_offset >> 3;
2256 uint8_t required_bits_in_first_octet = 8 - (bit_offset % 8);
2257
2258 if(required_bits_in_first_octet > total_no_of_bits)
2259 {
2260 /* the required bits don't extend to the end of the first octet */
2261 uint8_t right_shift = required_bits_in_first_octet - total_no_of_bits;
2262 value = (tvb_get_uint8(tvb, octet_offset) >> right_shift) & bit_mask8[total_no_of_bits % 8];
2263 }
2264 else
2265 {
2266 uint8_t remaining_bit_length = total_no_of_bits;
2267
2268 /* get the bits up to the first octet boundary */
2269 value = 0;
2270 required_bits_in_first_octet %= 8;
2271 if(required_bits_in_first_octet != 0)
2272 {
2273 value = tvb_get_uint8(tvb, octet_offset) & bit_mask8[required_bits_in_first_octet];
2274 remaining_bit_length -= required_bits_in_first_octet;
2275 octet_offset ++;
2276 }
2277 /* take the biggest words, shorts or octets that we can */
2278 while (remaining_bit_length > 7)
2279 {
2280 switch (remaining_bit_length >> 4)
2281 {
2282 case 0:
2283 /* 8 - 15 bits. (note that 0 - 7 would have dropped out of the while() loop) */
2284 value <<= 8;
2285 value += tvb_get_uint8(tvb, octet_offset);
2286 remaining_bit_length -= 8;
2287 octet_offset ++;
2288 break;
2289
2290 case 1:
2291 /* 16 - 31 bits */
2292 value <<= 16;
2293 value += tvb_get_ntohs(tvb, octet_offset);
2294 remaining_bit_length -= 16;
2295 octet_offset += 2;
2296 break;
2297
2298 case 2:
2299 case 3:
2300 /* 32 - 63 bits */
2301 value <<= 32;
2302 value += tvb_get_ntohl(tvb, octet_offset);
2303 remaining_bit_length -= 32;
2304 octet_offset += 4;
2305 break;
2306
2307 default:
2308 /* 64 bits (or more???) */
2309 value = tvb_get_ntoh64(tvb, octet_offset);
2310 remaining_bit_length -= 64;
2311 octet_offset += 8;
2312 break;
2313 }
2314 }
2315 /* get bits from any partial octet at the tail */
2316 if(remaining_bit_length)
2317 {
2318 value <<= remaining_bit_length;
2319 value += (tvb_get_uint8(tvb, octet_offset) >> (8 - remaining_bit_length));
2320 }
2321 }
2322 return value;
2323}
2324
2325/*
2326 * Offset should be given in bits from the start of the tvb.
2327 * Bits within octet are numbered from LSB (0) to MSB (7). Bit at bit_offset is return value least significant bit.
2328 * The function tolerates requests for more than 64 bits, but will only return the least significant 64 bits.
2329 */
2330static uint64_t
2331_tvb_get_bits64_le(tvbuff_t *tvb, unsigned bit_offset, const int total_no_of_bits)
2332{
2333 uint64_t value = 0;
2334 unsigned octet_offset = bit_offset / 8;
2335 int remaining_bits = total_no_of_bits;
2336 int shift = 0;
2337
2338 if (remaining_bits > 64)
2339 {
2340 remaining_bits = 64;
2341 }
2342
2343 if (bit_offset % 8)
2344 {
2345 /* not aligned, extract bits from first octet */
2346 shift = 8 - (bit_offset % 8);
2347 value = tvb_get_uint8(tvb, octet_offset) >> (bit_offset % 8);
2348 if (shift > remaining_bits)
2349 {
2350 /* keep only the requested bits */
2351 value &= (UINT64_C(1)1UL << remaining_bits) - 1;
2352 remaining_bits = 0;
2353 }
2354 else
2355 {
2356 remaining_bits -= shift;
2357 }
2358 octet_offset++;
2359 }
2360
2361 while (remaining_bits > 0)
2362 {
2363 /* take the biggest words, shorts or octets that we can */
2364 if (remaining_bits >= 32)
2365 {
2366 value |= ((uint64_t)tvb_get_letohl(tvb, octet_offset) << shift);
2367 shift += 32;
2368 remaining_bits -= 32;
2369 octet_offset += 4;
2370 }
2371 else if (remaining_bits >= 16)
2372 {
2373 value |= ((uint64_t)tvb_get_letohs(tvb, octet_offset) << shift);
2374 shift += 16;
2375 remaining_bits -= 16;
2376 octet_offset += 2;
2377 }
2378 else if (remaining_bits >= 8)
2379 {
2380 value |= ((uint64_t)tvb_get_uint8(tvb, octet_offset) << shift);
2381 shift += 8;
2382 remaining_bits -= 8;
2383 octet_offset += 1;
2384 }
2385 else
2386 {
2387 unsigned mask = (1 << remaining_bits) - 1;
2388 value |= (((uint64_t)tvb_get_uint8(tvb, octet_offset) & mask) << shift);
2389 shift += remaining_bits;
2390 remaining_bits = 0;
2391 octet_offset += 1;
2392 }
2393 }
2394 return value;
2395}
2396
2397/* Get 1 - 32 bits (should be deprecated as same as tvb_get_bits32??) */
2398uint32_t
2399tvb_get_bits(tvbuff_t *tvb, const unsigned bit_offset, const int no_of_bits, const unsigned encoding)
2400{
2401 return (uint32_t)tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
2402}
2403
2404static int
2405tvb_find_uint8_generic(tvbuff_t *tvb, unsigned abs_offset, unsigned limit, uint8_t needle)
2406{
2407 const uint8_t *ptr;
2408 const uint8_t *result;
2409
2410 ptr = ensure_contiguous(tvb, abs_offset, limit); /* tvb_get_ptr() */
2411 if (!ptr)
2412 return -1;
2413
2414 result = (const uint8_t *) memchr(ptr, needle, limit);
2415 if (!result)
2416 return -1;
2417
2418 return (int) ((result - ptr) + abs_offset);
2419}
2420
2421/* Find first occurrence of needle in tvbuff, starting at offset. Searches
2422 * at most maxlength number of bytes; if maxlength is -1, searches to
2423 * end of tvbuff.
2424 * Returns the offset of the found needle, or -1 if not found.
2425 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
2426 * in that case, -1 will be returned if the boundary is reached before
2427 * finding needle. */
2428int
2429tvb_find_uint8(tvbuff_t *tvb, const int offset, const int maxlength, const uint8_t needle)
2430{
2431 const uint8_t *result;
2432 unsigned abs_offset = 0;
2433 unsigned limit = 0;
2434 int exception;
2435
2436 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2436, "tvb && tvb->initialized"
))))
;
2437
2438 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &limit);
2439 if (exception)
2440 THROW(exception)except_throw(1, (exception), ((void*)0));
2441
2442 /* Only search to end of tvbuff, w/o throwing exception. */
2443 if (maxlength >= 0 && limit > (unsigned) maxlength) {
2444 /* Maximum length doesn't go past end of tvbuff; search
2445 to that value. */
2446 limit = (unsigned) maxlength;
2447 }
2448
2449 /* If we have real data, perform our search now. */
2450 if (tvb->real_data) {
2451 result = (const uint8_t *)memchr(tvb->real_data + abs_offset, needle, limit);
2452 if (result == NULL((void*)0)) {
2453 return -1;
2454 }
2455 else {
2456 return (int) (result - tvb->real_data);
2457 }
2458 }
2459
2460 if (tvb->ops->tvb_find_uint8)
2461 return tvb->ops->tvb_find_uint8(tvb, abs_offset, limit, needle);
2462
2463 return tvb_find_uint8_generic(tvb, offset, limit, needle);
2464}
2465
2466/* Same as tvb_find_uint8() with 16bit needle. */
2467int
2468tvb_find_uint16(tvbuff_t *tvb, const int offset, const int maxlength,
2469 const uint16_t needle)
2470{
2471 unsigned abs_offset = 0;
2472 unsigned limit = 0;
2473 int exception;
2474
2475 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &limit);
2476 if (exception)
2477 THROW(exception)except_throw(1, (exception), ((void*)0));
2478
2479 /* Only search to end of tvbuff, w/o throwing exception. */
2480 if (maxlength >= 0 && limit > (unsigned) maxlength) {
2481 /* Maximum length doesn't go past end of tvbuff; search
2482 to that value. */
2483 limit = (unsigned) maxlength;
2484 }
2485
2486 const uint8_t needle1 = ((needle & 0xFF00) >> 8);
2487 const uint8_t needle2 = ((needle & 0x00FF) >> 0);
2488 unsigned searched_bytes = 0;
2489 unsigned pos = abs_offset;
2490
2491 do {
2492 int offset1 =
2493 tvb_find_uint8(tvb, pos, limit - searched_bytes, needle1);
2494 int offset2 = -1;
2495
2496 if (offset1 == -1) {
2497 return -1;
2498 }
2499
2500 searched_bytes = (unsigned)offset1 - abs_offset + 1;
2501
2502 if (searched_bytes >= limit) {
2503 return -1;
2504 }
2505
2506 offset2 = tvb_find_uint8(tvb, offset1 + 1, 1, needle2);
2507
2508 searched_bytes += 1;
2509
2510 if (offset2 != -1) {
2511 if (searched_bytes > limit) {
2512 return -1;
2513 }
2514 return offset1;
2515 }
2516
2517 pos = offset1 + 1;
2518 } while (searched_bytes < limit);
2519
2520 return -1;
2521}
2522
2523static inline int
2524tvb_ws_mempbrk_uint8_generic(tvbuff_t *tvb, unsigned abs_offset, unsigned limit, const ws_mempbrk_pattern* pattern, unsigned char *found_needle)
2525{
2526 const uint8_t *ptr;
2527 const uint8_t *result;
2528
2529 ptr = ensure_contiguous(tvb, abs_offset, limit); /* tvb_get_ptr */
2530 if (!ptr)
2531 return -1;
2532
2533 result = ws_mempbrk_exec(ptr, limit, pattern, found_needle);
2534 if (!result)
2535 return -1;
2536
2537 return (int) ((result - ptr) + abs_offset);
2538}
2539
2540
2541/* Find first occurrence of any of the pattern chars in tvbuff, starting at offset.
2542 * Searches at most maxlength number of bytes; if maxlength is -1, searches
2543 * to end of tvbuff.
2544 * Returns the offset of the found needle, or -1 if not found.
2545 * Will not throw an exception, even if maxlength exceeds boundary of tvbuff;
2546 * in that case, -1 will be returned if the boundary is reached before
2547 * finding needle. */
2548int
2549tvb_ws_mempbrk_pattern_uint8(tvbuff_t *tvb, const int offset, const int maxlength,
2550 const ws_mempbrk_pattern* pattern, unsigned char *found_needle)
2551{
2552 const uint8_t *result;
2553 unsigned abs_offset = 0;
2554 unsigned limit = 0;
2555 int exception;
2556
2557 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2557, "tvb && tvb->initialized"
))))
;
2558
2559 exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &limit);
2560 if (exception)
2561 THROW(exception)except_throw(1, (exception), ((void*)0));
2562
2563 /* Only search to end of tvbuff, w/o throwing exception. */
2564 if (limit > (unsigned) maxlength) {
2565 /* Maximum length doesn't go past end of tvbuff; search
2566 to that value. */
2567 limit = maxlength;
2568 }
2569
2570 /* If we have real data, perform our search now. */
2571 if (tvb->real_data) {
2572 result = ws_mempbrk_exec(tvb->real_data + abs_offset, limit, pattern, found_needle);
2573 if (result == NULL((void*)0)) {
2574 return -1;
2575 }
2576 else {
2577 return (int) (result - tvb->real_data);
2578 }
2579 }
2580
2581 if (tvb->ops->tvb_ws_mempbrk_pattern_uint8)
2582 return tvb->ops->tvb_ws_mempbrk_pattern_uint8(tvb, abs_offset, limit, pattern, found_needle);
2583
2584 return tvb_ws_mempbrk_uint8_generic(tvb, abs_offset, limit, pattern, found_needle);
2585}
2586
2587/* Find size of stringz (NUL-terminated string) by looking for terminating
2588 * NUL. The size of the string includes the terminating NUL.
2589 *
2590 * If the NUL isn't found, it throws the appropriate exception.
2591 */
2592unsigned
2593tvb_strsize(tvbuff_t *tvb, const int offset)
2594{
2595 unsigned abs_offset = 0, junk_length;
2596 int nul_offset;
2597
2598 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2598, "tvb && tvb->initialized"
))))
;
2599
2600 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
2601 nul_offset = tvb_find_uint8(tvb, abs_offset, -1, 0);
2602 if (nul_offset == -1) {
2603 /*
2604 * OK, we hit the end of the tvbuff, so we should throw
2605 * an exception.
2606 */
2607 if (tvb->length < tvb->contained_length) {
2608 THROW(BoundsError)except_throw(1, (1), ((void*)0));
2609 } else if (tvb->flags & TVBUFF_FRAGMENT0x00000001) {
2610 THROW(FragmentBoundsError)except_throw(1, (4), ((void*)0));
2611 } else if (tvb->length < tvb->reported_length) {
2612 THROW(ContainedBoundsError)except_throw(1, (2), ((void*)0));
2613 } else {
2614 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
2615 }
2616 }
2617 return (nul_offset - abs_offset) + 1;
2618}
2619
2620/* UTF-16/UCS-2 version of tvb_strsize */
2621/* Returns number of bytes including the (two-bytes) null terminator */
2622unsigned
2623tvb_unicode_strsize(tvbuff_t *tvb, const int offset)
2624{
2625 unsigned i = 0;
2626 gunichar2 uchar;
2627
2628 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2628, "tvb && tvb->initialized"
))))
;
2629
2630 do {
2631 /* Endianness doesn't matter when looking for null */
2632 uchar = tvb_get_ntohs(tvb, offset + i);
2633 i += 2;
2634 } while(uchar != 0);
2635
2636 return i;
2637}
2638
2639/* Find length of string by looking for end of string ('\0'), up to
2640 * 'maxlength' characters'; if 'maxlength' is -1, searches to end
2641 * of tvbuff.
2642 * Returns -1 if 'maxlength' reached before finding EOS. */
2643int
2644tvb_strnlen(tvbuff_t *tvb, const int offset, const unsigned maxlength)
2645{
2646 int result_offset;
2647 unsigned abs_offset = 0, junk_length;
2648
2649 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2649, "tvb && tvb->initialized"
))))
;
2650
2651 check_offset_length(tvb, offset, 0, &abs_offset, &junk_length);
2652
2653 result_offset = tvb_find_uint8(tvb, abs_offset, maxlength, 0);
2654
2655 if (result_offset == -1) {
2656 return -1;
2657 }
2658 else {
2659 return result_offset - abs_offset;
2660 }
2661}
2662
2663/*
2664 * Implement strneql etc
2665 */
2666
2667/*
2668 * Call strncmp after checking if enough chars left, returning 0 if
2669 * it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2670 */
2671int
2672tvb_strneql(tvbuff_t *tvb, const int offset, const char *str, const size_t size)
2673{
2674 const uint8_t *ptr;
2675
2676 ptr = ensure_contiguous_no_exception(tvb, offset, (int)size, NULL((void*)0));
2677
2678 if (ptr) {
2679 int cmp = strncmp((const char *)ptr, str, size);
2680
2681 /*
2682 * Return 0 if equal, -1 otherwise.
2683 */
2684 return (cmp == 0 ? 0 : -1);
2685 } else {
2686 /*
2687 * Not enough characters in the tvbuff to match the
2688 * string.
2689 */
2690 return -1;
2691 }
2692}
2693
2694/*
2695 * Call g_ascii_strncasecmp after checking if enough chars left, returning
2696 * 0 if it returns 0 (meaning "equal") and -1 otherwise, otherwise return -1.
2697 */
2698int
2699tvb_strncaseeql(tvbuff_t *tvb, const int offset, const char *str, const size_t size)
2700{
2701 const uint8_t *ptr;
2702
2703 ptr = ensure_contiguous_no_exception(tvb, offset, (int)size, NULL((void*)0));
2704
2705 if (ptr) {
2706 int cmp = g_ascii_strncasecmp((const char *)ptr, str, size);
2707
2708 /*
2709 * Return 0 if equal, -1 otherwise.
2710 */
2711 return (cmp == 0 ? 0 : -1);
2712 } else {
2713 /*
2714 * Not enough characters in the tvbuff to match the
2715 * string.
2716 */
2717 return -1;
2718 }
2719}
2720
2721/*
2722 * Check that the tvbuff contains at least size bytes, starting at
2723 * offset, and that those bytes are equal to str. Return 0 for success
2724 * and -1 for error. This function does not throw an exception.
2725 */
2726int
2727tvb_memeql(tvbuff_t *tvb, const int offset, const uint8_t *str, size_t size)
2728{
2729 const uint8_t *ptr;
2730
2731 ptr = ensure_contiguous_no_exception(tvb, offset, (int) size, NULL((void*)0));
2732
2733 if (ptr) {
2734 int cmp = memcmp(ptr, str, size);
2735
2736 /*
2737 * Return 0 if equal, -1 otherwise.
2738 */
2739 return (cmp == 0 ? 0 : -1);
2740 } else {
2741 /*
2742 * Not enough characters in the tvbuff to match the
2743 * string.
2744 */
2745 return -1;
2746 }
2747}
2748
2749/**
2750 * Format the data in the tvb from offset for size.
2751 */
2752char *
2753tvb_format_text(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int size)
2754{
2755 const uint8_t *ptr;
2756 int len;
2757
2758 len = (size > 0) ? size : 0;
2759
2760 ptr = ensure_contiguous(tvb, offset, size);
2761 return format_text(scope, (const char*)ptr, len);
2762}
2763
2764/*
2765 * Format the data in the tvb from offset for length ...
2766 */
2767char *
2768tvb_format_text_wsp(wmem_allocator_t* allocator, tvbuff_t *tvb, const int offset, const int size)
2769{
2770 const uint8_t *ptr;
2771 int len;
2772
2773 len = (size > 0) ? size : 0;
2774
2775 ptr = ensure_contiguous(tvb, offset, size);
2776 return format_text_wsp(allocator, (const char*)ptr, len);
2777}
2778
2779/**
2780 * Like "tvb_format_text()", but for null-padded strings; don't show
2781 * the null padding characters as "\000".
2782 */
2783char *
2784tvb_format_stringzpad(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int size)
2785{
2786 const uint8_t *ptr, *p;
2787 int len;
2788 int stringlen;
2789
2790 len = (size > 0) ? size : 0;
2791
2792 ptr = ensure_contiguous(tvb, offset, size);
2793 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2794 ;
2795 return format_text(scope, (const char*)ptr, stringlen);
2796}
2797
2798/*
2799 * Like "tvb_format_text_wsp()", but for null-padded strings; don't show
2800 * the null padding characters as "\000".
2801 */
2802char *
2803tvb_format_stringzpad_wsp(wmem_allocator_t* allocator, tvbuff_t *tvb, const int offset, const int size)
2804{
2805 const uint8_t *ptr, *p;
2806 int len;
2807 int stringlen;
2808
2809 len = (size > 0) ? size : 0;
2810
2811 ptr = ensure_contiguous(tvb, offset, size);
2812 for (p = ptr, stringlen = 0; stringlen < len && *p != '\0'; p++, stringlen++)
2813 ;
2814 return format_text_wsp(allocator, (const char*)ptr, stringlen);
2815}
2816
2817/*
2818 * All string functions below take a scope as an argument.
2819 *
2820 *
2821 * If scope is NULL, memory is allocated with g_malloc() and user must
2822 * explicitly free it with g_free().
2823 * If scope is not NULL, memory is allocated with the corresponding pool
2824 * lifetime.
2825 *
2826 * All functions throw an exception if the tvbuff ends before the string
2827 * does.
2828 */
2829
2830/*
2831 * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2832 * of bytes referred to by the tvbuff, offset, and length as an ASCII string,
2833 * with all bytes with the high-order bit set being invalid, and return a
2834 * pointer to a UTF-8 string, allocated using the wmem scope.
2835 *
2836 * Octets with the highest bit set will be converted to the Unicode
2837 * REPLACEMENT CHARACTER.
2838 */
2839static uint8_t *
2840tvb_get_ascii_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length)
2841{
2842 const uint8_t *ptr;
2843
2844 ptr = ensure_contiguous(tvb, offset, length);
2845 return get_ascii_string(scope, ptr, length);
2846}
2847
2848/*
2849 * Given a wmem scope, a tvbuff, an offset, a length, and a translation table,
2850 * treat the string of bytes referred to by the tvbuff, offset, and length
2851 * as a string encoded using one octet per character, with octets with the
2852 * high-order bit clear being mapped by the translation table to 2-byte
2853 * Unicode Basic Multilingual Plane characters (including REPLACEMENT
2854 * CHARACTER) and octets with the high-order bit set being mapped to
2855 * REPLACEMENT CHARACTER, and return a pointer to a UTF-8 string,
2856 * allocated using the wmem scope.
2857 *
2858 * Octets with the highest bit set will be converted to the Unicode
2859 * REPLACEMENT CHARACTER.
2860 */
2861static uint8_t *
2862tvb_get_iso_646_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length, const gunichar2 table[0x80])
2863{
2864 const uint8_t *ptr;
2865
2866 ptr = ensure_contiguous(tvb, offset, length);
2867 return get_iso_646_string(scope, ptr, length, table);
2868}
2869
2870/*
2871 * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2872 * of bytes referred to by the tvbuff, the offset. and the length as a UTF-8
2873 * string, and return a pointer to a UTF-8 string, allocated using the wmem
2874 * scope, with all ill-formed sequences replaced with the Unicode REPLACEMENT
2875 * CHARACTER according to the recommended "best practices" given in the Unicode
2876 * Standard and specified by W3C/WHATWG.
2877 *
2878 * Note that in conformance with the Unicode Standard, this treats three
2879 * byte sequences corresponding to UTF-16 surrogate halves (paired or unpaired)
2880 * and two byte overlong encodings of 7-bit ASCII characters as invalid and
2881 * substitutes REPLACEMENT CHARACTER for them. Explicit support for nonstandard
2882 * derivative encoding formats (e.g. CESU-8, Java Modified UTF-8, WTF-8) could
2883 * be added later.
2884 */
2885static uint8_t *
2886tvb_get_utf_8_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int length)
2887{
2888 const uint8_t *ptr;
2889
2890 ptr = ensure_contiguous(tvb, offset, length);
2891 return get_utf_8_string(scope, ptr, length);
2892}
2893
2894/*
2895 * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2896 * of bytes referred to by the tvbuff, the offset, and the length as a
2897 * raw string, and return a pointer to that string, allocated using the
2898 * wmem scope. This means a null is appended at the end, but no replacement
2899 * checking is done otherwise, unlike tvb_get_utf_8_string().
2900 *
2901 * Also, this one allows a length of -1 to mean get all, but does not
2902 * allow a negative offset.
2903 */
2904static inline uint8_t *
2905tvb_get_raw_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int length)
2906{
2907 uint8_t *strbuf;
2908 int abs_length = length;
2909
2910 DISSECTOR_ASSERT(offset >= 0)((void) ((offset >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2910, "offset >= 0"
))))
;
2911 DISSECTOR_ASSERT(abs_length >= -1)((void) ((abs_length >= -1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 2911, "abs_length >= -1"
))))
;
2912
2913 if (abs_length < 0)
2914 abs_length = tvb->length - offset;
2915
2916 tvb_ensure_bytes_exist(tvb, (unsigned)offset, abs_length);
2917 strbuf = (uint8_t *)wmem_alloc(scope, abs_length + 1);
2918 tvb_memcpy(tvb, strbuf, offset, abs_length);
2919 strbuf[abs_length] = '\0';
2920 return strbuf;
2921}
2922
2923/*
2924 * Given a wmem scope, a tvbuff, an offset, and a length, treat the string
2925 * of bytes referred to by the tvbuff, the offset, and the length as an
2926 * ISO 8859/1 string, and return a pointer to a UTF-8 string, allocated
2927 * using the wmem scope.
2928 */
2929static uint8_t *
2930tvb_get_string_8859_1(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length)
2931{
2932 const uint8_t *ptr;
2933
2934 ptr = ensure_contiguous(tvb, offset, length);
2935 return get_8859_1_string(scope, ptr, length);
2936}
2937
2938/*
2939 * Given a wmem scope, a tvbuff, an offset, a length, and a translation
2940 * table, treat the string of bytes referred to by the tvbuff, the offset,
2941 * and the length as a string encoded using one octet per character, with
2942 * octets with the high-order bit clear being ASCII and octets with the
2943 * high-order bit set being mapped by the translation table to 2-byte
2944 * Unicode Basic Multilingual Plane characters (including REPLACEMENT
2945 * CHARACTER), and return a pointer to a UTF-8 string, allocated with the
2946 * wmem scope.
2947 */
2948static uint8_t *
2949tvb_get_string_unichar2(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length, const gunichar2 table[0x80])
2950{
2951 const uint8_t *ptr;
2952
2953 ptr = ensure_contiguous(tvb, offset, length);
2954 return get_unichar2_string(scope, ptr, length, table);
2955}
2956
2957/*
2958 * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2959 * giving the byte order, treat the string of bytes referred to by the
2960 * tvbuff, the offset, and the length as a UCS-2 encoded string in
2961 * the byte order in question, containing characters from the Basic
2962 * Multilingual Plane (plane 0) of Unicode, and return a pointer to a
2963 * UTF-8 string, allocated with the wmem scope.
2964 *
2965 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN.
2966 *
2967 * Specify length in bytes.
2968 *
2969 * XXX - should map lead and trail surrogate values to REPLACEMENT
2970 * CHARACTERs (0xFFFD)?
2971 * XXX - if there are an odd number of bytes, should put a
2972 * REPLACEMENT CHARACTER at the end.
2973 */
2974static uint8_t *
2975tvb_get_ucs_2_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int length, const unsigned encoding)
2976{
2977 const uint8_t *ptr;
2978
2979 ptr = ensure_contiguous(tvb, offset, length);
2980 return get_ucs_2_string(scope, ptr, length, encoding);
2981}
2982
2983/*
2984 * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
2985 * giving the byte order, treat the string of bytes referred to by the
2986 * tvbuff, the offset, and the length as a UTF-16 encoded string in
2987 * the byte order in question, and return a pointer to a UTF-8 string,
2988 * allocated with the wmem scope.
2989 *
2990 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN.
2991 *
2992 * Specify length in bytes.
2993 *
2994 * XXX - should map surrogate errors to REPLACEMENT CHARACTERs (0xFFFD).
2995 * XXX - should map code points > 10FFFF to REPLACEMENT CHARACTERs.
2996 * XXX - if there are an odd number of bytes, should put a
2997 * REPLACEMENT CHARACTER at the end.
2998 */
2999static uint8_t *
3000tvb_get_utf_16_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int length, const unsigned encoding)
3001{
3002 const uint8_t *ptr;
3003
3004 ptr = ensure_contiguous(tvb, offset, length);
3005 return get_utf_16_string(scope, ptr, length, encoding);
3006}
3007
3008/*
3009 * Given a wmem scope, a tvbuff, an offset, a length, and an encoding
3010 * giving the byte order, treat the string of bytes referred to by the
3011 * tvbuff, the offset, and the length as a UCS-4 encoded string in
3012 * the byte order in question, and return a pointer to a UTF-8 string,
3013 * allocated with the wmem scope.
3014 *
3015 * Encoding parameter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
3016 *
3017 * Specify length in bytes
3018 *
3019 * XXX - should map lead and trail surrogate values to a "substitute"
3020 * UTF-8 character?
3021 * XXX - should map code points > 10FFFF to REPLACEMENT CHARACTERs.
3022 * XXX - if the number of bytes isn't a multiple of 4, should put a
3023 * REPLACEMENT CHARACTER at the end.
3024 */
3025static char *
3026tvb_get_ucs_4_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int length, const unsigned encoding)
3027{
3028 const uint8_t *ptr;
3029
3030 ptr = ensure_contiguous(tvb, offset, length);
3031 return (char*)get_ucs_4_string(scope, ptr, length, encoding);
3032}
3033
3034char *
3035tvb_get_ts_23_038_7bits_string_packed(wmem_allocator_t *scope, tvbuff_t *tvb,
3036 const int bit_offset, int no_of_chars)
3037{
3038 int in_offset = bit_offset >> 3; /* Current pointer to the input buffer */
3039 int length = ((no_of_chars + 1) * 7 + (bit_offset & 0x07)) >> 3;
3040 const uint8_t *ptr;
3041
3042 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3042, "tvb && tvb->initialized"
))))
;
3043
3044 ptr = ensure_contiguous(tvb, in_offset, length);
3045 return (char*)get_ts_23_038_7bits_string_packed(scope, ptr, bit_offset, no_of_chars);
3046}
3047
3048char *
3049tvb_get_ts_23_038_7bits_string_unpacked(wmem_allocator_t *scope, tvbuff_t *tvb,
3050 const int offset, int length)
3051{
3052 const uint8_t *ptr;
3053
3054 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3054, "tvb && tvb->initialized"
))))
;
3055
3056 ptr = ensure_contiguous(tvb, offset, length);
3057 return (char*)get_ts_23_038_7bits_string_unpacked(scope, ptr, length);
3058}
3059
3060char *
3061tvb_get_etsi_ts_102_221_annex_a_string(wmem_allocator_t *scope, tvbuff_t *tvb,
3062 const int offset, int length)
3063{
3064 const uint8_t *ptr;
3065
3066 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3066, "tvb && tvb->initialized"
))))
;
3067
3068 ptr = ensure_contiguous(tvb, offset, length);
3069 return (char*)get_etsi_ts_102_221_annex_a_string(scope, ptr, length);
3070}
3071
3072char *
3073tvb_get_ascii_7bits_string(wmem_allocator_t *scope, tvbuff_t *tvb,
3074 const int bit_offset, int no_of_chars)
3075{
3076 int in_offset = bit_offset >> 3; /* Current pointer to the input buffer */
3077 int length = ((no_of_chars + 1) * 7 + (bit_offset & 0x07)) >> 3;
3078 const uint8_t *ptr;
3079
3080 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3080, "tvb && tvb->initialized"
))))
;
3081
3082 ptr = ensure_contiguous(tvb, in_offset, length);
3083 return (char*)get_ascii_7bits_string(scope, ptr, bit_offset, no_of_chars);
3084}
3085
3086/*
3087 * Given a wmem scope, a tvbuff, an offset, a length, and a translation
3088 * table, treat the string of bytes referred to by the tvbuff, the offset,
3089 * and the length as a string encoded using one octet per character, with
3090 * octets being mapped by the translation table to 2-byte Unicode Basic
3091 * Multilingual Plane characters (including REPLACEMENT CHARACTER), and
3092 * return a pointer to a UTF-8 string, allocated with the wmem scope.
3093 */
3094static uint8_t *
3095tvb_get_nonascii_unichar2_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length, const gunichar2 table[256])
3096{
3097 const uint8_t *ptr;
3098
3099 ptr = ensure_contiguous(tvb, offset, length);
3100 return get_nonascii_unichar2_string(scope, ptr, length, table);
3101}
3102
3103/*
3104 * Given a wmem scope, a tvbuff, an offset, and a length, treat the bytes
3105 * referred to by the tvbuff, offset, and length as a GB18030 encoded string,
3106 * and return a pointer to a UTF-8 string, allocated with the wmem scope,
3107 * converted having substituted REPLACEMENT CHARACTER according to the
3108 * Unicode Standard 5.22 U+FFFD Substitution for Conversion.
3109 * ( https://www.unicode.org/versions/Unicode13.0.0/ch05.pdf )
3110 *
3111 * As expected, this will also decode GBK and GB2312 strings.
3112 */
3113static uint8_t *
3114tvb_get_gb18030_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length)
3115{
3116 const uint8_t *ptr;
3117
3118 ptr = ensure_contiguous(tvb, offset, length);
3119 return get_gb18030_string(scope, ptr, length);
3120}
3121
3122/*
3123 * Given a wmem scope, a tvbuff, an offset, and a length, treat the bytes
3124 * referred to by the tvbuff, offset, and length as a EUC-KR encoded string,
3125 * and return a pointer to a UTF-8 string, allocated with the wmem scope,
3126 * converted having substituted REPLACEMENT CHARACTER according to the
3127 * Unicode Standard 5.22 U+FFFD Substitution for Conversion.
3128 * ( https://www.unicode.org/versions/Unicode13.0.0/ch05.pdf )
3129 */
3130static uint8_t *
3131tvb_get_euc_kr_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length)
3132{
3133 const uint8_t *ptr;
3134
3135 ptr = ensure_contiguous(tvb, offset, length);
3136 return get_euc_kr_string(scope, ptr, length);
3137}
3138
3139static uint8_t *
3140tvb_get_t61_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length)
3141{
3142 const uint8_t *ptr;
3143
3144 ptr = ensure_contiguous(tvb, offset, length);
3145 return get_t61_string(scope, ptr, length);
3146}
3147
3148/*
3149 * Encoding tables for BCD strings.
3150 */
3151static const dgt_set_t Dgt0_9_bcd = {
3152 {
3153 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
3154 '0','1','2','3','4','5','6','7','8','9','?','?','?','?','?','?'
3155 }
3156};
3157
3158static const dgt_set_t Dgt_keypad_abc_tbcd = {
3159 {
3160 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
3161 '0','1','2','3','4','5','6','7','8','9','*','#','a','b','c','?'
3162 }
3163};
3164
3165static const dgt_set_t Dgt_ansi_tbcd = {
3166 {
3167 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
3168 '0','1','2','3','4','5','6','7','8','9','?','B','C','*','#','?'
3169 }
3170};
3171
3172static const dgt_set_t Dgt_dect_standard_4bits_tbcd = {
3173 {
3174 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
3175 '0','1','2','3','4','5','6','7','8','9','?',' ','?','?','?','?'
3176 }
3177};
3178
3179static uint8_t *
3180tvb_get_apn_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset,
3181 int length)
3182{
3183 wmem_strbuf_t *str;
3184
3185 /*
3186 * This is a domain name.
3187 *
3188 * 3GPP TS 23.003, section 19.4.2 "Fully Qualified Domain Names
3189 * (FQDNs)", subsection 19.4.2.1 "General", says:
3190 *
3191 * The encoding of any identifier used as part of a Fully
3192 * Qualified Domain Name (FQDN) shall follow the Name Syntax
3193 * defined in IETF RFC 2181 [18], IETF RFC 1035 [19] and
3194 * IETF RFC 1123 [20]. An FQDN consists of one or more
3195 * labels. Each label is coded as a one octet length field
3196 * followed by that number of octets coded as 8 bit ASCII
3197 * characters.
3198 *
3199 * so this does not appear to use full-blown DNS compression -
3200 * the upper 2 bits of the length don't indicate that it's a
3201 * pointer or an extended label (RFC 2673).
3202 */
3203 str = wmem_strbuf_new_sized(scope, length + 1);
3204 if (length > 0) {
3205 const uint8_t *ptr;
3206
3207 ptr = ensure_contiguous(tvb, offset, length);
3208
3209 for (;;) {
3210 unsigned label_len;
3211
3212 /*
3213 * Process this label.
3214 */
3215 label_len = *ptr;
3216 ptr++;
3217 length--;
3218
3219 while (label_len != 0) {
3220 uint8_t ch;
3221
3222 if (length == 0)
3223 goto end;
3224
3225 ch = *ptr;
3226 if (ch < 0x80)
3227 wmem_strbuf_append_c(str, ch);
3228 else
3229 wmem_strbuf_append_unichar_repl(str)wmem_strbuf_append_unichar(str, 0x00FFFD);
3230 ptr++;
3231 label_len--;
3232 length--;
3233 }
3234
3235 if (length == 0)
3236 goto end;
3237
3238 wmem_strbuf_append_c(str, '.');
3239 }
3240 }
3241
3242end:
3243 return (uint8_t *) wmem_strbuf_finalize(str);
3244}
3245
3246static uint8_t *
3247tvb_get_dect_standard_8bits_string(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int length)
3248{
3249 const uint8_t *ptr;
3250
3251 ptr = ensure_contiguous(tvb, offset, length);
3252 return get_dect_standard_8bits_string(scope, ptr, length);
3253}
3254
3255/*
3256 * Given a tvbuff, an offset, a length, and an encoding, allocate a
3257 * buffer big enough to hold a non-null-terminated string of that length
3258 * at that offset, plus a trailing '\0', copy into the buffer the
3259 * string as converted from the appropriate encoding to UTF-8, and
3260 * return a pointer to the string.
3261 */
3262uint8_t *
3263tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset,
3264 const int length, const unsigned encoding)
3265{
3266 uint8_t *strptr;
3267 bool_Bool odd, skip_first;
3268
3269 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3269, "tvb && tvb->initialized"
))))
;
3270
3271 /* make sure length = -1 fails */
3272 if (length < 0) {
3273 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
3274 }
3275
3276 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
3277
3278 case ENC_ASCII0x00000000:
3279 default:
3280 /*
3281 * For now, we treat bogus values as meaning
3282 * "ASCII" rather than reporting an error,
3283 * for the benefit of old dissectors written
3284 * when the last argument to proto_tree_add_item()
3285 * was a bool for the byte order, not an
3286 * encoding value, and passed non-zero values
3287 * other than true to mean "little-endian".
3288 */
3289 strptr = tvb_get_ascii_string(scope, tvb, offset, length);
3290 break;
3291
3292 case ENC_UTF_80x00000002:
3293 strptr = tvb_get_utf_8_string(scope, tvb, offset, length);
3294 break;
3295
3296 case ENC_UTF_160x00000004:
3297 strptr = tvb_get_utf_16_string(scope, tvb, offset, length,
3298 encoding & (ENC_LITTLE_ENDIAN0x80000000|ENC_BOM0x20000000));
3299 break;
3300
3301 case ENC_UCS_20x00000006:
3302 strptr = tvb_get_ucs_2_string(scope, tvb, offset, length,
3303 encoding & (ENC_LITTLE_ENDIAN0x80000000|ENC_BOM0x20000000));
3304 break;
3305
3306 case ENC_UCS_40x00000008:
3307 strptr = (uint8_t*)tvb_get_ucs_4_string(scope, tvb, offset, length,
3308 encoding & (ENC_LITTLE_ENDIAN0x80000000|ENC_BOM0x20000000));
3309 break;
3310
3311 case ENC_ISO_8859_10x0000000A:
3312 /*
3313 * ISO 8859-1 printable code point values are equal
3314 * to the equivalent Unicode code point value, so
3315 * no translation table is needed.
3316 */
3317 strptr = tvb_get_string_8859_1(scope, tvb, offset, length);
3318 break;
3319
3320 case ENC_ISO_8859_20x0000000C:
3321 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_2);
3322 break;
3323
3324 case ENC_ISO_8859_30x0000000E:
3325 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_3);
3326 break;
3327
3328 case ENC_ISO_8859_40x00000010:
3329 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_4);
3330 break;
3331
3332 case ENC_ISO_8859_50x00000012:
3333 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_5);
3334 break;
3335
3336 case ENC_ISO_8859_60x00000014:
3337 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_6);
3338 break;
3339
3340 case ENC_ISO_8859_70x00000016:
3341 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_7);
3342 break;
3343
3344 case ENC_ISO_8859_80x00000018:
3345 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_8);
3346 break;
3347
3348 case ENC_ISO_8859_90x0000001A:
3349 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_9);
3350 break;
3351
3352 case ENC_ISO_8859_100x0000001C:
3353 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_10);
3354 break;
3355
3356 case ENC_ISO_8859_110x0000001E:
3357 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_11);
3358 break;
3359
3360 case ENC_ISO_8859_130x00000022:
3361 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_13);
3362 break;
3363
3364 case ENC_ISO_8859_140x00000024:
3365 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_14);
3366 break;
3367
3368 case ENC_ISO_8859_150x00000026:
3369 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_15);
3370 break;
3371
3372 case ENC_ISO_8859_160x00000028:
3373 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_iso_8859_16);
3374 break;
3375
3376 case ENC_WINDOWS_12500x0000002A:
3377 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp1250);
3378 break;
3379
3380 case ENC_WINDOWS_12510x0000003C:
3381 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp1251);
3382 break;
3383
3384 case ENC_WINDOWS_12520x0000003A:
3385 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp1252);
3386 break;
3387
3388 case ENC_MAC_ROMAN0x00000030:
3389 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_mac_roman);
3390 break;
3391
3392 case ENC_CP4370x00000032:
3393 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp437);
3394 break;
3395
3396 case ENC_CP8550x0000003E:
3397 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp855);
3398 break;
3399
3400 case ENC_CP8660x00000040:
3401 strptr = tvb_get_string_unichar2(scope, tvb, offset, length, charset_table_cp866);
3402 break;
3403
3404 case ENC_ISO_646_BASIC0x00000042:
3405 strptr = tvb_get_iso_646_string(scope, tvb, offset, length, charset_table_iso_646_basic);
3406 break;
3407
3408 case ENC_3GPP_TS_23_038_7BITS_PACKED0x0000002C:
3409 {
3410 int bit_offset = offset << 3;
3411 int no_of_chars = (length << 3) / 7;
3412 strptr = (uint8_t*)tvb_get_ts_23_038_7bits_string_packed(scope, tvb, bit_offset, no_of_chars);
3413 }
3414 break;
3415
3416 case ENC_ASCII_7BITS0x00000034:
3417 {
3418 int bit_offset = offset << 3;
3419 int no_of_chars = (length << 3) / 7;
3420 strptr = (uint8_t*)tvb_get_ascii_7bits_string(scope, tvb, bit_offset, no_of_chars);
3421 }
3422 break;
3423
3424 case ENC_EBCDIC0x0000002E:
3425 /*
3426 * "Common" EBCDIC, covering all characters with the
3427 * same code point in all Roman-alphabet EBCDIC code
3428 * pages.
3429 */
3430 strptr = tvb_get_nonascii_unichar2_string(scope, tvb, offset, length, charset_table_ebcdic);
3431 break;
3432
3433 case ENC_EBCDIC_CP0370x00000038:
3434 /*
3435 * EBCDIC code page 037.
3436 */
3437 strptr = tvb_get_nonascii_unichar2_string(scope, tvb, offset, length, charset_table_ebcdic_cp037);
3438 break;
3439
3440 case ENC_EBCDIC_CP5000x00000060:
3441 /*
3442 * EBCDIC code page 500.
3443 */
3444 strptr = tvb_get_nonascii_unichar2_string(scope, tvb, offset, length, charset_table_ebcdic_cp500);
3445 break;
3446
3447 case ENC_T610x00000036:
3448 strptr = tvb_get_t61_string(scope, tvb, offset, length);
3449 break;
3450
3451 case ENC_BCD_DIGITS_0_90x00000044:
3452 /*
3453 * Packed BCD, with digits 0-9.
3454 */
3455 odd = (encoding & ENC_BCD_ODD_NUM_DIG0x00010000) >> 16;
3456 skip_first = (encoding & ENC_BCD_SKIP_FIRST0x00020000) >> 17;
3457 strptr = (uint8_t*)tvb_get_bcd_string(scope, tvb, offset, length, &Dgt0_9_bcd, skip_first, odd, !(encoding & ENC_LITTLE_ENDIAN0x80000000));
3458 break;
3459
3460 case ENC_KEYPAD_ABC_TBCD0x00000046:
3461 /*
3462 * Keypad-with-a/b/c "telephony BCD" - packed BCD, with
3463 * digits 0-9 and symbols *, #, a, b, and c.
3464 */
3465 odd = (encoding & ENC_BCD_ODD_NUM_DIG0x00010000) >> 16;
3466 skip_first = (encoding & ENC_BCD_SKIP_FIRST0x00020000) >> 17;
3467 strptr = (uint8_t*)tvb_get_bcd_string(scope, tvb, offset, length, &Dgt_keypad_abc_tbcd, skip_first, odd, !(encoding & ENC_LITTLE_ENDIAN0x80000000));
3468 break;
3469
3470 case ENC_KEYPAD_BC_TBCD0x00000048:
3471 /*
3472 * Keypad-with-B/C "telephony BCD" - packed BCD, with
3473 * digits 0-9 and symbols B, C, *, and #.
3474 */
3475 odd = (encoding & ENC_BCD_ODD_NUM_DIG0x00010000) >> 16;
3476 skip_first = (encoding & ENC_BCD_SKIP_FIRST0x00020000) >> 17;
3477 strptr = (uint8_t*)tvb_get_bcd_string(scope, tvb, offset, length, &Dgt_ansi_tbcd, skip_first, odd, !(encoding & ENC_LITTLE_ENDIAN0x80000000));
3478 break;
3479
3480 case ENC_3GPP_TS_23_038_7BITS_UNPACKED0x0000004C:
3481 strptr = (uint8_t*)tvb_get_ts_23_038_7bits_string_unpacked(scope, tvb, offset, length);
3482 break;
3483
3484 case ENC_ETSI_TS_102_221_ANNEX_A0x0000004E:
3485 strptr = (uint8_t*)tvb_get_etsi_ts_102_221_annex_a_string(scope, tvb, offset, length);
3486 break;
3487
3488 case ENC_GB180300x00000050:
3489 strptr = tvb_get_gb18030_string(scope, tvb, offset, length);
3490 break;
3491
3492 case ENC_EUC_KR0x00000052:
3493 strptr = tvb_get_euc_kr_string(scope, tvb, offset, length);
3494 break;
3495
3496 case ENC_APN_STR0x00000054:
3497 strptr = tvb_get_apn_string(scope, tvb, offset, length);
3498 break;
3499
3500 case ENC_DECT_STANDARD_8BITS0x00000056:
3501 strptr = tvb_get_dect_standard_8bits_string(scope, tvb, offset, length);
3502 break;
3503
3504 case ENC_DECT_STANDARD_4BITS_TBCD0x00000058:
3505 /*
3506 * DECT standard 4bits "telephony BCD" - packed BCD, with
3507 * digits 0-9 and symbol SPACE for 0xb.
3508 */
3509 odd = (encoding & ENC_BCD_ODD_NUM_DIG0x00010000) >> 16;
3510 skip_first = (encoding & ENC_BCD_SKIP_FIRST0x00020000) >> 17;
3511 strptr = (uint8_t*)tvb_get_bcd_string(scope, tvb, offset, length, &Dgt_dect_standard_4bits_tbcd, skip_first, odd, false0);
3512 break;
3513 }
3514 return strptr;
3515}
3516
3517/*
3518 * This is like tvb_get_string_enc(), except that it handles null-padded
3519 * strings.
3520 *
3521 * Currently, string values are stored as UTF-8 null-terminated strings,
3522 * so nothing needs to be done differently for null-padded strings; we
3523 * could save a little memory by not storing the null padding.
3524 *
3525 * If we ever store string values differently, in a fashion that doesn't
3526 * involve null termination, that might change.
3527 */
3528uint8_t *
3529tvb_get_stringzpad(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset,
3530 const int length, const unsigned encoding)
3531{
3532 return tvb_get_string_enc(scope, tvb, offset, length, encoding);
3533}
3534
3535/*
3536 * These routines are like the above routines, except that they handle
3537 * null-terminated strings. They find the length of that string (and
3538 * throw an exception if the tvbuff ends before we find the null), and
3539 * also return through a pointer the length of the string, in bytes,
3540 * including the terminating null (the terminating null being 2 bytes
3541 * for UCS-2 and UTF-16, 4 bytes for UCS-4, and 1 byte for other
3542 * encodings).
3543 */
3544static uint8_t *
3545tvb_get_ascii_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp)
3546{
3547 unsigned size;
3548 const uint8_t *ptr;
3549
3550 size = tvb_strsize(tvb, offset);
3551 ptr = ensure_contiguous(tvb, offset, size);
3552 /* XXX, conversion between signed/unsigned integer */
3553 if (lengthp)
3554 *lengthp = size;
3555 return get_ascii_string(scope, ptr, size);
3556}
3557
3558static uint8_t *
3559tvb_get_iso_646_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp, const gunichar2 table[0x80])
3560{
3561 unsigned size;
3562 const uint8_t *ptr;
3563
3564 size = tvb_strsize(tvb, offset);
3565 ptr = ensure_contiguous(tvb, offset, size);
3566 /* XXX, conversion between signed/unsigned integer */
3567 if (lengthp)
3568 *lengthp = size;
3569 return get_iso_646_string(scope, ptr, size, table);
3570}
3571
3572static uint8_t *
3573tvb_get_utf_8_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int *lengthp)
3574{
3575 unsigned size;
3576 const uint8_t *ptr;
3577
3578 size = tvb_strsize(tvb, offset);
3579 ptr = ensure_contiguous(tvb, offset, size);
3580 /* XXX, conversion between signed/unsigned integer */
3581 if (lengthp)
3582 *lengthp = size;
3583 return get_utf_8_string(scope, ptr, size);
3584}
3585
3586static uint8_t *
3587tvb_get_stringz_8859_1(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp)
3588{
3589 unsigned size;
3590 const uint8_t *ptr;
3591
3592 size = tvb_strsize(tvb, offset);
3593 ptr = ensure_contiguous(tvb, offset, size);
3594 /* XXX, conversion between signed/unsigned integer */
3595 if (lengthp)
3596 *lengthp = size;
3597 return get_8859_1_string(scope, ptr, size);
3598}
3599
3600static uint8_t *
3601tvb_get_stringz_unichar2(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp, const gunichar2 table[0x80])
3602{
3603 unsigned size;
3604 const uint8_t *ptr;
3605
3606 size = tvb_strsize(tvb, offset);
3607 ptr = ensure_contiguous(tvb, offset, size);
3608 /* XXX, conversion between signed/unsigned integer */
3609 if (lengthp)
3610 *lengthp = size;
3611 return get_unichar2_string(scope, ptr, size, table);
3612}
3613
3614/*
3615 * Given a tvbuff and an offset, with the offset assumed to refer to
3616 * a null-terminated string, find the length of that string (and throw
3617 * an exception if the tvbuff ends before we find the null), ensure that
3618 * the TVB is flat, and return a pointer to the string (in the TVB).
3619 * Also return the length of the string (including the terminating null)
3620 * through a pointer.
3621 *
3622 * As long as we aren't using composite TVBs, this saves the cycles used
3623 * (often unnecessarily) in allocating a buffer and copying the string into
3624 * it. (If we do start using composite TVBs, we may want to replace this
3625 * function with the _ephemeral version.)
3626 */
3627const uint8_t *
3628tvb_get_const_stringz(tvbuff_t *tvb, const int offset, int *lengthp)
3629{
3630 unsigned size;
3631 const uint8_t *strptr;
3632
3633 size = tvb_strsize(tvb, offset);
3634 strptr = ensure_contiguous(tvb, offset, size);
3635 if (lengthp)
3636 *lengthp = size;
3637 return strptr;
3638}
3639
3640static char *
3641tvb_get_ucs_2_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int *lengthp, const unsigned encoding)
3642{
3643 int size; /* Number of bytes in string */
3644 const uint8_t *ptr;
3645
3646 size = tvb_unicode_strsize(tvb, offset);
3647 ptr = ensure_contiguous(tvb, offset, size);
3648 /* XXX, conversion between signed/unsigned integer */
3649 if (lengthp)
3650 *lengthp = size;
3651 return (char*)get_ucs_2_string(scope, ptr, size, encoding);
3652}
3653
3654static char *
3655tvb_get_utf_16_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int *lengthp, const unsigned encoding)
3656{
3657 int size;
3658 const uint8_t *ptr;
3659
3660 size = tvb_unicode_strsize(tvb, offset);
3661 ptr = ensure_contiguous(tvb, offset, size);
3662 /* XXX, conversion between signed/unsigned integer */
3663 if (lengthp)
3664 *lengthp = size;
3665 return (char*)get_utf_16_string(scope, ptr, size, encoding);
3666}
3667
3668static char *
3669tvb_get_ucs_4_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int *lengthp, const unsigned encoding)
3670{
3671 int size;
3672 gunichar uchar;
3673 const uint8_t *ptr;
3674
3675 size = 0;
3676 do {
3677 /* Endianness doesn't matter when looking for null */
3678 uchar = tvb_get_ntohl(tvb, offset + size);
3679 size += 4;
3680 } while(uchar != 0);
3681
3682 ptr = ensure_contiguous(tvb, offset, size);
3683 /* XXX, conversion between signed/unsigned integer */
3684 if (lengthp)
3685 *lengthp = size;
3686 return (char*)get_ucs_4_string(scope, ptr, size, encoding);
3687}
3688
3689static uint8_t *
3690tvb_get_nonascii_unichar2_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp, const gunichar2 table[256])
3691{
3692 unsigned size;
3693 const uint8_t *ptr;
3694
3695 size = tvb_strsize(tvb, offset);
3696 ptr = ensure_contiguous(tvb, offset, size);
3697 /* XXX, conversion between signed/unsigned integer */
3698 if (lengthp)
3699 *lengthp = size;
3700 return get_nonascii_unichar2_string(scope, ptr, size, table);
3701}
3702
3703static uint8_t *
3704tvb_get_t61_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp)
3705{
3706 unsigned size;
3707 const uint8_t *ptr;
3708
3709 size = tvb_strsize(tvb, offset);
3710 ptr = ensure_contiguous(tvb, offset, size);
3711 /* XXX, conversion between signed/unsigned integer */
3712 if (lengthp)
3713 *lengthp = size;
3714 return get_t61_string(scope, ptr, size);
3715}
3716
3717static uint8_t *
3718tvb_get_gb18030_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp)
3719{
3720 unsigned size;
3721 const uint8_t *ptr;
3722
3723 size = tvb_strsize(tvb, offset);
3724 ptr = ensure_contiguous(tvb, offset, size);
3725 /* XXX, conversion between signed/unsigned integer */
3726 if (lengthp)
3727 *lengthp = size;
3728 return get_gb18030_string(scope, ptr, size);
3729}
3730
3731static uint8_t *
3732tvb_get_euc_kr_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp)
3733{
3734 unsigned size;
3735 const uint8_t *ptr;
3736
3737 size = tvb_strsize(tvb, offset);
3738 ptr = ensure_contiguous(tvb, offset, size);
3739 /* XXX, conversion between signed/unsigned integer */
3740 if (lengthp)
3741 *lengthp = size;
3742 return get_euc_kr_string(scope, ptr, size);
3743}
3744
3745static uint8_t *
3746tvb_get_dect_standard_8bits_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, int offset, int *lengthp)
3747{
3748 unsigned size;
3749 const uint8_t *ptr;
3750
3751 size = tvb_strsize(tvb, offset);
3752 ptr = ensure_contiguous(tvb, offset, size);
3753 /* XXX, conversion between signed/unsigned integer */
3754 if (lengthp)
3755 *lengthp = size;
3756 return get_dect_standard_8bits_string(scope, ptr, size);
3757}
3758
3759uint8_t *
3760tvb_get_stringz_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int *lengthp, const unsigned encoding)
3761{
3762 uint8_t *strptr;
3763
3764 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3764, "tvb && tvb->initialized"
))))
;
3765
3766 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
3767
3768 case ENC_ASCII0x00000000:
3769 default:
3770 /*
3771 * For now, we treat bogus values as meaning
3772 * "ASCII" rather than reporting an error,
3773 * for the benefit of old dissectors written
3774 * when the last argument to proto_tree_add_item()
3775 * was a bool for the byte order, not an
3776 * encoding value, and passed non-zero values
3777 * other than true to mean "little-endian".
3778 */
3779 strptr = tvb_get_ascii_stringz(scope, tvb, offset, lengthp);
3780 break;
3781
3782 case ENC_UTF_80x00000002:
3783 /*
3784 * XXX - should map all invalid UTF-8 sequences
3785 * to a "substitute" UTF-8 character.
3786 * XXX - should map code points > 10FFFF to REPLACEMENT
3787 * CHARACTERs.
3788 */
3789 strptr = tvb_get_utf_8_stringz(scope, tvb, offset, lengthp);
3790 break;
3791
3792 case ENC_UTF_160x00000004:
3793 strptr = (uint8_t*)tvb_get_utf_16_stringz(scope, tvb, offset, lengthp,
3794 encoding & (ENC_LITTLE_ENDIAN0x80000000|ENC_BOM0x20000000));
3795 break;
3796
3797 case ENC_UCS_20x00000006:
3798 strptr = (uint8_t*)tvb_get_ucs_2_stringz(scope, tvb, offset, lengthp,
3799 encoding & (ENC_LITTLE_ENDIAN0x80000000|ENC_BOM0x20000000));
3800 break;
3801
3802 case ENC_UCS_40x00000008:
3803 strptr = (uint8_t*)tvb_get_ucs_4_stringz(scope, tvb, offset, lengthp,
3804 encoding & (ENC_LITTLE_ENDIAN0x80000000|ENC_BOM0x20000000));
3805 break;
3806
3807 case ENC_ISO_8859_10x0000000A:
3808 /*
3809 * ISO 8859-1 printable code point values are equal
3810 * to the equivalent Unicode code point value, so
3811 * no translation table is needed.
3812 */
3813 strptr = tvb_get_stringz_8859_1(scope, tvb, offset, lengthp);
3814 break;
3815
3816 case ENC_ISO_8859_20x0000000C:
3817 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_2);
3818 break;
3819
3820 case ENC_ISO_8859_30x0000000E:
3821 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_3);
3822 break;
3823
3824 case ENC_ISO_8859_40x00000010:
3825 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_4);
3826 break;
3827
3828 case ENC_ISO_8859_50x00000012:
3829 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_5);
3830 break;
3831
3832 case ENC_ISO_8859_60x00000014:
3833 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_6);
3834 break;
3835
3836 case ENC_ISO_8859_70x00000016:
3837 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_7);
3838 break;
3839
3840 case ENC_ISO_8859_80x00000018:
3841 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_8);
3842 break;
3843
3844 case ENC_ISO_8859_90x0000001A:
3845 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_9);
3846 break;
3847
3848 case ENC_ISO_8859_100x0000001C:
3849 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_10);
3850 break;
3851
3852 case ENC_ISO_8859_110x0000001E:
3853 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_11);
3854 break;
3855
3856 case ENC_ISO_8859_130x00000022:
3857 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_13);
3858 break;
3859
3860 case ENC_ISO_8859_140x00000024:
3861 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_14);
3862 break;
3863
3864 case ENC_ISO_8859_150x00000026:
3865 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_15);
3866 break;
3867
3868 case ENC_ISO_8859_160x00000028:
3869 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_iso_8859_16);
3870 break;
3871
3872 case ENC_WINDOWS_12500x0000002A:
3873 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp1250);
3874 break;
3875
3876 case ENC_WINDOWS_12510x0000003C:
3877 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp1251);
3878 break;
3879
3880 case ENC_WINDOWS_12520x0000003A:
3881 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp1252);
3882 break;
3883
3884 case ENC_MAC_ROMAN0x00000030:
3885 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_mac_roman);
3886 break;
3887
3888 case ENC_CP4370x00000032:
3889 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp437);
3890 break;
3891
3892 case ENC_CP8550x0000003E:
3893 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp855);
3894 break;
3895
3896 case ENC_CP8660x00000040:
3897 strptr = tvb_get_stringz_unichar2(scope, tvb, offset, lengthp, charset_table_cp866);
3898 break;
3899
3900 case ENC_ISO_646_BASIC0x00000042:
3901 strptr = tvb_get_iso_646_stringz(scope, tvb, offset, lengthp, charset_table_iso_646_basic);
3902 break;
3903
3904 case ENC_3GPP_TS_23_038_7BITS_PACKED0x0000002C:
3905 case ENC_3GPP_TS_23_038_7BITS_UNPACKED0x0000004C:
3906 case ENC_ETSI_TS_102_221_ANNEX_A0x0000004E:
3907 REPORT_DISSECTOR_BUG("TS 23.038 7bits has no null character and doesn't support null-terminated strings")proto_report_dissector_bug("TS 23.038 7bits has no null character and doesn't support null-terminated strings"
)
;
3908 break;
3909
3910 case ENC_ASCII_7BITS0x00000034:
3911 REPORT_DISSECTOR_BUG("tvb_get_stringz_enc function with ENC_ASCII_7BITS not implemented yet")proto_report_dissector_bug("tvb_get_stringz_enc function with ENC_ASCII_7BITS not implemented yet"
)
;
3912 break;
3913
3914 case ENC_EBCDIC0x0000002E:
3915 /*
3916 * "Common" EBCDIC, covering all characters with the
3917 * same code point in all Roman-alphabet EBCDIC code
3918 * pages.
3919 */
3920 strptr = tvb_get_nonascii_unichar2_stringz(scope, tvb, offset, lengthp, charset_table_ebcdic);
3921 break;
3922
3923 case ENC_EBCDIC_CP0370x00000038:
3924 /*
3925 * EBCDIC code page 037.
3926 */
3927 strptr = tvb_get_nonascii_unichar2_stringz(scope, tvb, offset, lengthp, charset_table_ebcdic_cp037);
3928 break;
3929
3930 case ENC_EBCDIC_CP5000x00000060:
3931 /*
3932 * EBCDIC code page 500.
3933 */
3934 strptr = tvb_get_nonascii_unichar2_stringz(scope, tvb, offset, lengthp, charset_table_ebcdic_cp500);
3935 break;
3936
3937 case ENC_T610x00000036:
3938 strptr = tvb_get_t61_stringz(scope, tvb, offset, lengthp);
3939 break;
3940
3941 case ENC_GB180300x00000050:
3942 strptr = tvb_get_gb18030_stringz(scope, tvb, offset, lengthp);
3943 break;
3944
3945 case ENC_EUC_KR0x00000052:
3946 strptr = tvb_get_euc_kr_stringz(scope, tvb, offset, lengthp);
3947 break;
3948
3949 case ENC_DECT_STANDARD_8BITS0x00000056:
3950 strptr = tvb_get_dect_standard_8bits_stringz(scope, tvb, offset, lengthp);
3951 break;
3952 }
3953
3954 return strptr;
3955}
3956
3957/* Looks for a stringz (NUL-terminated string) in tvbuff and copies
3958 * no more than bufsize number of bytes, including terminating NUL, to buffer.
3959 * Returns length of string (not including terminating NUL), or -1 if the string was
3960 * truncated in the buffer due to not having reached the terminating NUL.
3961 * In this way, it acts like snprintf().
3962 *
3963 * bufsize MUST be greater than 0.
3964 *
3965 * When processing a packet where the remaining number of bytes is less
3966 * than bufsize, an exception is not thrown if the end of the packet
3967 * is reached before the NUL is found. If no NUL is found before reaching
3968 * the end of the short packet, -1 is still returned, and the string
3969 * is truncated with a NUL, albeit not at buffer[bufsize - 1], but
3970 * at the correct spot, terminating the string.
3971 *
3972 * *bytes_copied will contain the number of bytes actually copied,
3973 * including the terminating-NUL.
3974 */
3975static int
3976_tvb_get_raw_bytes_as_stringz(tvbuff_t *tvb, const int offset, const unsigned bufsize, uint8_t* buffer, int *bytes_copied)
3977{
3978 int stringlen;
3979 unsigned abs_offset = 0;
3980 int limit;
3981 unsigned len = 0;
3982 bool_Bool decreased_max = false0;
3983
3984 /* Only read to end of tvbuff, w/o throwing exception. */
3985 check_offset_length(tvb, offset, -1, &abs_offset, &len);
3986
3987 /* There must at least be room for the terminating NUL. */
3988 DISSECTOR_ASSERT(bufsize != 0)((void) ((bufsize != 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 3988, "bufsize != 0"
))))
;
3989
3990 /* If there's no room for anything else, just return the NUL. */
3991 if (bufsize == 1) {
3992 buffer[0] = 0;
3993 *bytes_copied = 1;
3994 return 0;
3995 }
3996
3997 /* check_offset_length() won't throw an exception if we're
3998 * looking at the byte immediately after the end of the tvbuff. */
3999 if (len == 0) {
4000 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4001 }
4002
4003 /*
4004 * If we've been passed a negative number, bufsize will
4005 * be huge.
4006 */
4007 DISSECTOR_ASSERT(bufsize <= INT_MAX)((void) ((bufsize <= 2147483647) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4007, "bufsize <= 2147483647"
))))
;
4008
4009 if ((unsigned)len < bufsize) {
4010 limit = len;
4011 decreased_max = true1;
4012 }
4013 else {
4014 limit = bufsize;
4015 }
4016
4017 stringlen = tvb_strnlen(tvb, abs_offset, limit - 1);
4018 /* If NUL wasn't found, copy the data and return -1 */
4019 if (stringlen == -1) {
4020 tvb_memcpy(tvb, buffer, abs_offset, limit);
4021 if (decreased_max) {
4022 buffer[limit] = 0;
4023 /* Add 1 for the extra NUL that we set at buffer[limit],
4024 * pretending that it was copied as part of the string. */
4025 *bytes_copied = limit + 1;
4026 }
4027 else {
4028 *bytes_copied = limit;
4029 }
4030 return -1;
4031 }
4032
4033 /* Copy the string to buffer */
4034 tvb_memcpy(tvb, buffer, abs_offset, stringlen + 1);
4035 *bytes_copied = stringlen + 1;
4036 return stringlen;
4037}
4038
4039int
4040tvb_get_raw_bytes_as_stringz(tvbuff_t *tvb, const int offset, const unsigned bufsize, uint8_t* buffer)
4041{
4042 int len, bytes_copied;
4043
4044 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4044, "tvb && tvb->initialized"
))))
;
4045
4046 len = _tvb_get_raw_bytes_as_stringz(tvb, offset, bufsize, buffer, &bytes_copied);
4047
4048 if (len == -1) {
4049 buffer[bufsize - 1] = 0;
4050 return bytes_copied - 1;
4051 }
4052 else {
4053 return len;
4054 }
4055}
4056
4057/*
4058 * Given a tvbuff, an offset into the tvbuff, a buffer, and a buffer size,
4059 * extract as many raw bytes from the tvbuff, starting at the offset,
4060 * as 1) are available in the tvbuff and 2) will fit in the buffer, leaving
4061 * room for a terminating NUL.
4062 */
4063int
4064tvb_get_raw_bytes_as_string(tvbuff_t *tvb, const int offset, char *buffer, size_t bufsize)
4065{
4066 int len = 0;
4067
4068 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4068, "tvb && tvb->initialized"
))))
;
4069
4070 /* There must be room for the string and the terminating NUL. */
4071 DISSECTOR_ASSERT(bufsize > 0)((void) ((bufsize > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4071, "bufsize > 0"
))))
;
4072
4073 DISSECTOR_ASSERT(bufsize - 1 < INT_MAX)((void) ((bufsize - 1 < 2147483647) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4073, "bufsize - 1 < 2147483647"
))))
;
4074
4075 len = tvb_captured_length_remaining(tvb, offset);
4076 if (len <= 0) {
4077 buffer[0] = '\0';
4078 return 0;
4079 }
4080 if (len > (int)(bufsize - 1))
4081 len = (int)(bufsize - 1);
4082
4083 /* Copy the string to buffer */
4084 tvb_memcpy(tvb, buffer, offset, len);
4085 buffer[len] = '\0';
4086 return len;
4087}
4088
4089bool_Bool
4090tvb_ascii_isprint(tvbuff_t *tvb, const int offset, const int length)
4091{
4092 const uint8_t* buf = tvb_get_ptr(tvb, offset, length);
4093 unsigned abs_offset, abs_length = length;
4094
4095 if (length == -1) {
4096 /* tvb_get_ptr has already checked for exceptions. */
4097 compute_offset_and_remaining(tvb, offset, &abs_offset, &abs_length);
4098 }
4099 for (unsigned i = 0; i < abs_length; i++, buf++)
4100 if (!g_ascii_isprint(*buf)((g_ascii_table[(guchar) (*buf)] & G_ASCII_PRINT) != 0))
4101 return false0;
4102
4103 return true1;
4104}
4105
4106bool_Bool
4107tvb_utf_8_isprint(tvbuff_t *tvb, const int offset, const int length)
4108{
4109 const uint8_t* buf = tvb_get_ptr(tvb, offset, length);
4110 unsigned abs_offset, abs_length = length;
4111
4112 if (length == -1) {
4113 /* tvb_get_ptr has already checked for exceptions. */
4114 compute_offset_and_remaining(tvb, offset, &abs_offset, &abs_length);
4115 }
4116
4117 return isprint_utf8_string((const char*)buf, abs_length);
4118}
4119
4120bool_Bool
4121tvb_ascii_isdigit(tvbuff_t *tvb, const int offset, const int length)
4122{
4123 const uint8_t* buf = tvb_get_ptr(tvb, offset, length);
4124 unsigned abs_offset, abs_length = length;
4125
4126 if (length == -1) {
4127 /* tvb_get_ptr has already checked for exceptions. */
4128 compute_offset_and_remaining(tvb, offset, &abs_offset, &abs_length);
4129 }
4130 for (unsigned i = 0; i < abs_length; i++, buf++)
4131 if (!g_ascii_isdigit(*buf)((g_ascii_table[(guchar) (*buf)] & G_ASCII_DIGIT) != 0))
4132 return false0;
4133
4134 return true1;
4135}
4136
4137static ws_mempbrk_pattern pbrk_crlf;
4138/*
4139 * Given a tvbuff, an offset into the tvbuff, and a length that starts
4140 * at that offset (which may be -1 for "all the way to the end of the
4141 * tvbuff"), find the end of the (putative) line that starts at the
4142 * specified offset in the tvbuff, going no further than the specified
4143 * length.
4144 *
4145 * Return the length of the line (not counting the line terminator at
4146 * the end), or, if we don't find a line terminator:
4147 *
4148 * if "desegment" is true, return -1;
4149 *
4150 * if "desegment" is false, return the amount of data remaining in
4151 * the buffer.
4152 *
4153 * If "next_offset" is not NULL, set "*next_offset" to the offset of the
4154 * character past the line terminator, or past the end of the buffer if
4155 * we don't find a line terminator. (It's not set if we return -1.)
4156 */
4157int
4158tvb_find_line_end(tvbuff_t *tvb, const int offset, int len, int *next_offset, const bool_Bool desegment)
4159{
4160 int eob_offset;
4161 int eol_offset;
4162 int linelen;
4163 unsigned char found_needle = 0;
4164 static bool_Bool compiled = false0;
4165
4166 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4166, "tvb && tvb->initialized"
))))
;
4167
4168 if (len == -1) {
4169 len = _tvb_captured_length_remaining(tvb, offset);
4170 /* if offset is past the end of the tvbuff, len is now 0 */
4171 }
4172
4173 eob_offset = offset + len;
4174
4175 if (!compiled) {
4176 ws_mempbrk_compile(&pbrk_crlf, "\r\n");
4177 compiled = true1;
4178 }
4179
4180 /*
4181 * Look either for a CR or an LF.
4182 */
4183 eol_offset = tvb_ws_mempbrk_pattern_uint8(tvb, offset, len, &pbrk_crlf, &found_needle);
4184 if (eol_offset == -1) {
4185 /*
4186 * No CR or LF - line is presumably continued in next packet.
4187 */
4188 if (desegment) {
4189 /*
4190 * Tell our caller we saw no EOL, so they can
4191 * try to desegment and get the entire line
4192 * into one tvbuff.
4193 */
4194 return -1;
4195 } else {
4196 /*
4197 * Pretend the line runs to the end of the tvbuff.
4198 */
4199 linelen = eob_offset - offset;
4200 if (next_offset)
4201 *next_offset = eob_offset;
4202 }
4203 } else {
4204 /*
4205 * Find the number of bytes between the starting offset
4206 * and the CR or LF.
4207 */
4208 linelen = eol_offset - offset;
4209
4210 /*
4211 * Is it a CR?
4212 */
4213 if (found_needle == '\r') {
4214 /*
4215 * Yes - is it followed by an LF?
4216 */
4217 if (eol_offset + 1 >= eob_offset) {
4218 /*
4219 * Dunno - the next byte isn't in this
4220 * tvbuff.
4221 */
4222 if (desegment) {
4223 /*
4224 * We'll return -1, although that
4225 * runs the risk that if the line
4226 * really *is* terminated with a CR,
4227 * we won't properly dissect this
4228 * tvbuff.
4229 *
4230 * It's probably more likely that
4231 * the line ends with CR-LF than
4232 * that it ends with CR by itself.
4233 */
4234 return -1;
4235 }
4236 } else {
4237 /*
4238 * Well, we can at least look at the next
4239 * byte.
4240 */
4241 if (tvb_get_uint8(tvb, eol_offset + 1) == '\n') {
4242 /*
4243 * It's an LF; skip over the CR.
4244 */
4245 eol_offset++;
4246 }
4247 }
4248 }
4249
4250 /*
4251 * Return the offset of the character after the last
4252 * character in the line, skipping over the last character
4253 * in the line terminator.
4254 */
4255 if (next_offset)
4256 *next_offset = eol_offset + 1;
4257 }
4258 return linelen;
4259}
4260
4261static ws_mempbrk_pattern pbrk_crlf_dquote;
4262/*
4263 * Given a tvbuff, an offset into the tvbuff, and a length that starts
4264 * at that offset (which may be -1 for "all the way to the end of the
4265 * tvbuff"), find the end of the (putative) line that starts at the
4266 * specified offset in the tvbuff, going no further than the specified
4267 * length.
4268 *
4269 * However, treat quoted strings inside the buffer specially - don't
4270 * treat newlines in quoted strings as line terminators.
4271 *
4272 * Return the length of the line (not counting the line terminator at
4273 * the end), or the amount of data remaining in the buffer if we don't
4274 * find a line terminator.
4275 *
4276 * If "next_offset" is not NULL, set "*next_offset" to the offset of the
4277 * character past the line terminator, or past the end of the buffer if
4278 * we don't find a line terminator.
4279 */
4280int
4281tvb_find_line_end_unquoted(tvbuff_t *tvb, const int offset, int len, int *next_offset)
4282{
4283 int cur_offset, char_offset;
4284 bool_Bool is_quoted;
4285 unsigned char c = 0;
4286 int eob_offset;
4287 int linelen;
4288 static bool_Bool compiled = false0;
4289
4290 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4290, "tvb && tvb->initialized"
))))
;
4291
4292 if (len == -1)
4293 len = _tvb_captured_length_remaining(tvb, offset);
4294
4295 if (!compiled) {
4296 ws_mempbrk_compile(&pbrk_crlf_dquote, "\r\n\"");
4297 compiled = true1;
4298 }
4299
4300 /*
4301 * XXX - what if "len" is still -1, meaning "offset is past the
4302 * end of the tvbuff"?
4303 */
4304 eob_offset = offset + len;
4305
4306 cur_offset = offset;
4307 is_quoted = false0;
4308 for (;;) {
4309 /*
4310 * Is this part of the string quoted?
4311 */
4312 if (is_quoted) {
4313 /*
4314 * Yes - look only for the terminating quote.
4315 */
4316 char_offset = tvb_find_uint8(tvb, cur_offset, len,
4317 '"');
4318 } else {
4319 /*
4320 * Look either for a CR, an LF, or a '"'.
4321 */
4322 char_offset = tvb_ws_mempbrk_pattern_uint8(tvb, cur_offset, len, &pbrk_crlf_dquote, &c);
4323 }
4324 if (char_offset == -1) {
4325 /*
4326 * Not found - line is presumably continued in
4327 * next packet.
4328 * We pretend the line runs to the end of the tvbuff.
4329 */
4330 linelen = eob_offset - offset;
4331 if (next_offset)
4332 *next_offset = eob_offset;
4333 break;
4334 }
4335
4336 if (is_quoted) {
4337 /*
4338 * We're processing a quoted string.
4339 * We only looked for ", so we know it's a ";
4340 * as we're processing a quoted string, it's a
4341 * closing quote.
4342 */
4343 is_quoted = false0;
4344 } else {
4345 /*
4346 * OK, what is it?
4347 */
4348 if (c == '"') {
4349 /*
4350 * Un-quoted "; it begins a quoted
4351 * string.
4352 */
4353 is_quoted = true1;
4354 } else {
4355 /*
4356 * It's a CR or LF; we've found a line
4357 * terminator.
4358 *
4359 * Find the number of bytes between the
4360 * starting offset and the CR or LF.
4361 */
4362 linelen = char_offset - offset;
4363
4364 /*
4365 * Is it a CR?
4366 */
4367 if (c == '\r') {
4368 /*
4369 * Yes; is it followed by an LF?
4370 */
4371 if (char_offset + 1 < eob_offset &&
4372 tvb_get_uint8(tvb, char_offset + 1)
4373 == '\n') {
4374 /*
4375 * Yes; skip over the CR.
4376 */
4377 char_offset++;
4378 }
4379 }
4380
4381 /*
4382 * Return the offset of the character after
4383 * the last character in the line, skipping
4384 * over the last character in the line
4385 * terminator, and quit.
4386 */
4387 if (next_offset)
4388 *next_offset = char_offset + 1;
4389 break;
4390 }
4391 }
4392
4393 /*
4394 * Step past the character we found.
4395 */
4396 cur_offset = char_offset + 1;
4397 if (cur_offset >= eob_offset) {
4398 /*
4399 * The character we found was the last character
4400 * in the tvbuff - line is presumably continued in
4401 * next packet.
4402 * We pretend the line runs to the end of the tvbuff.
4403 */
4404 linelen = eob_offset - offset;
4405 if (next_offset)
4406 *next_offset = eob_offset;
4407 break;
4408 }
4409 }
4410 return linelen;
4411}
4412
4413/*
4414 * Copied from the mgcp dissector. (This function should be moved to /epan )
4415 * tvb_skip_wsp - Returns the position in tvb of the first non-whitespace
4416 * character following offset or offset + maxlength -1 whichever
4417 * is smaller.
4418 *
4419 * Parameters:
4420 * tvb - The tvbuff in which we are skipping whitespace.
4421 * offset - The offset in tvb from which we begin trying to skip whitespace.
4422 * maxlength - The maximum distance from offset that we may try to skip
4423 * whitespace.
4424 *
4425 * Returns: The position in tvb of the first non-whitespace
4426 * character following offset or offset + maxlength -1 whichever
4427 * is smaller.
4428 */
4429int
4430tvb_skip_wsp(tvbuff_t *tvb, const int offset, const int maxlength)
4431{
4432 int counter;
4433 int end, tvb_len;
4434 uint8_t tempchar;
4435
4436 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4436, "tvb && tvb->initialized"
))))
;
4437
4438 /* Get the length remaining */
4439 /*tvb_len = tvb_captured_length(tvb);*/
4440 tvb_len = tvb->length;
4441
4442 end = offset + maxlength;
4443 if (end >= tvb_len)
4444 {
4445 end = tvb_len;
4446 }
4447
4448 /* Skip past spaces, tabs, CRs and LFs until run out or meet something else */
4449 for (counter = offset;
4450 counter < end &&
4451 ((tempchar = tvb_get_uint8(tvb,counter)) == ' ' ||
4452 tempchar == '\t' || tempchar == '\r' || tempchar == '\n');
4453 counter++);
4454
4455 return (counter);
4456}
4457
4458int
4459tvb_skip_wsp_return(tvbuff_t *tvb, const int offset)
4460{
4461 int counter;
4462 uint8_t tempchar;
4463
4464 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4464, "tvb && tvb->initialized"
))))
;
4465
4466 for (counter = offset; counter > 0 &&
4467 ((tempchar = tvb_get_uint8(tvb,counter)) == ' ' ||
4468 tempchar == '\t' || tempchar == '\n' || tempchar == '\r'); counter--);
4469 counter++;
4470
4471 return (counter);
4472}
4473
4474int
4475tvb_skip_uint8(tvbuff_t *tvb, int offset, const int maxlength, const uint8_t ch)
4476{
4477 int end, tvb_len;
4478
4479 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4479, "tvb && tvb->initialized"
))))
;
4480
4481 /* Get the length remaining */
4482 /*tvb_len = tvb_captured_length(tvb);*/
4483 tvb_len = tvb->length;
4484
4485 end = offset + maxlength;
4486 if (end >= tvb_len)
4487 end = tvb_len;
4488
4489 while (offset < end) {
4490 uint8_t tempch = tvb_get_uint8(tvb, offset);
4491
4492 if (tempch != ch)
4493 break;
4494 offset++;
4495 }
4496
4497 return offset;
4498}
4499
4500static ws_mempbrk_pattern pbrk_whitespace;
4501
4502int tvb_get_token_len(tvbuff_t *tvb, const int offset, int len, int *next_offset, const bool_Bool desegment)
4503{
4504 int eob_offset;
4505 int eot_offset;
4506 int tokenlen;
4507 unsigned char found_needle = 0;
4508 static bool_Bool compiled = false0;
4509
4510 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4510, "tvb && tvb->initialized"
))))
;
4511
4512 if (len == -1) {
4513 len = _tvb_captured_length_remaining(tvb, offset);
4514 /* if offset is past the end of the tvbuff, len is now 0 */
4515 }
4516
4517 eob_offset = offset + len;
4518
4519 if (!compiled) {
4520 ws_mempbrk_compile(&pbrk_whitespace, " \r\n");
4521 compiled = true1;
4522 }
4523
4524 /*
4525 * Look either for a space, CR, or LF.
4526 */
4527 eot_offset = tvb_ws_mempbrk_pattern_uint8(tvb, offset, len, &pbrk_whitespace, &found_needle);
4528 if (eot_offset == -1) {
4529 /*
4530 * No space, CR or LF - token is presumably continued in next packet.
4531 */
4532 if (desegment) {
4533 /*
4534 * Tell our caller we saw no whitespace, so they can
4535 * try to desegment and get the entire line
4536 * into one tvbuff.
4537 */
4538 return -1;
4539 }
4540 else {
4541 /*
4542 * Pretend the token runs to the end of the tvbuff.
4543 */
4544 tokenlen = eob_offset - offset;
4545 if (next_offset)
4546 *next_offset = eob_offset;
4547 }
4548 }
4549 else {
4550 /*
4551 * Find the number of bytes between the starting offset
4552 * and the space, CR or LF.
4553 */
4554 tokenlen = eot_offset - offset;
4555
4556 /*
4557 * Return the offset of the character after the last
4558 * character in the line, skipping over the last character
4559 * in the line terminator.
4560 */
4561 if (next_offset)
4562 *next_offset = eot_offset + 1;
4563 }
4564 return tokenlen;
4565}
4566
4567/*
4568 * Format a bunch of data from a tvbuff as bytes, returning a pointer
4569 * to the string with the formatted data, with "punct" as a byte
4570 * separator.
4571 */
4572char *
4573tvb_bytes_to_str_punct(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int len, const char punct)
4574{
4575 DISSECTOR_ASSERT(len >= 0)((void) ((len >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4575, "len >= 0"
))))
;
4576 return bytes_to_str_punct(scope, ensure_contiguous(tvb, offset, len), len, punct)bytes_to_str_punct_maxlen(scope, ensure_contiguous(tvb, offset
, len), len, punct, 24)
;
4577}
4578
4579/*
4580 * Given a wmem scope, a tvbuff, an offset, a length, an input digit
4581 * set, and a boolean indicator, fetch BCD-encoded digits from a
4582 * tvbuff starting from either the low or high half byte of the
4583 * first byte depending on the boolean indicator (true means "start
4584 * with the high half byte, ignoring the low half byte", and false
4585 * means "start with the low half byte and proceed to the high half
4586 * byte), formating the digits into characters according to the
4587 * input digit set, and return a pointer to a UTF-8 string, allocated
4588 * using the wmem scope. A nibble of 0xf is considered a 'filler'
4589 * and will end the conversion. Similarly if odd is set the last
4590 * high nibble will be omitted. (Note that if both skip_first and
4591 * odd are true, then both the first and last semi-octet are skipped,
4592 * i.e. an even number of nibbles are considered.)
4593 */
4594char *
4595tvb_get_bcd_string(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, int len, const dgt_set_t *dgt, bool_Bool skip_first, bool_Bool odd, bool_Bool bigendian)
4596{
4597 const uint8_t *ptr;
4598 int i = 0;
4599 char *digit_str;
4600 uint8_t octet, nibble;
4601
4602 DISSECTOR_ASSERT(tvb && tvb->initialized)((void) ((tvb && tvb->initialized) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4602, "tvb && tvb->initialized"
))))
;
4603
4604 if (len == -1) {
4605 /*
4606 * Run to the end of the captured data.
4607 *
4608 * XXX - captured, or total?
4609 */
4610 /*length = tvb_captured_length(tvb);*/
4611 len = tvb->length;
4612 if (len < offset) {
4613 return (char *)"";
4614 }
4615 len -= offset;
4616 }
4617
4618 ptr = ensure_contiguous(tvb, offset, len);
4619
4620 /*
4621 * XXX - map illegal digits (digits that map to 0) to REPLACEMENT
4622 * CHARACTER, and have all the tables in epan/tvbuff.c use 0 rather
4623 * than '?'?
4624 */
4625 digit_str = (char *)wmem_alloc(scope, len*2 + 1);
4626
4627 while (len > 0) {
4628 octet = *ptr;
4629 if (!skip_first) {
4630 if (bigendian) {
4631 nibble = (octet >> 4) & 0x0f;
4632 } else {
4633 nibble = octet & 0x0f;
4634 }
4635 if (nibble == 0x0f) {
4636 /*
4637 * Stop digit.
4638 */
4639 break;
4640 }
4641 digit_str[i] = dgt->out[nibble];
4642 i++;
4643 }
4644 skip_first = false0;
4645
4646 /*
4647 * unpack second value in byte
4648 */
4649 if (bigendian) {
4650 nibble = octet & 0x0f;
4651 } else {
4652 nibble = octet >> 4;
4653 }
4654
4655 if (nibble == 0x0f) {
4656 /*
4657 * This is the stop digit or a filler digit. Ignore
4658 * it.
4659 */
4660 break;
4661 }
4662 if ((len == 1) && (odd == true1 )){
4663 /* Last octet, skip last high nibble in case of odd number of digits */
4664 break;
4665 }
4666 digit_str[i] = dgt->out[nibble];
4667 i++;
4668
4669 ptr++;
4670 len--;
4671 }
4672 digit_str[i] = '\0';
4673 return digit_str;
4674}
4675
4676/* XXXX Fix me - needs odd indicator added */
4677const char *
4678tvb_bcd_dig_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int len, const dgt_set_t *dgt, bool_Bool skip_first)
4679{
4680 if (!dgt)
4681 dgt = &Dgt0_9_bcd;
4682
4683 return tvb_get_bcd_string(scope, tvb, offset, len, dgt, skip_first, false0, false0);
4684}
4685
4686const char *
4687tvb_bcd_dig_to_str_be(wmem_allocator_t *scope, tvbuff_t *tvb, const int offset, const int len, const dgt_set_t *dgt, bool_Bool skip_first)
4688{
4689 if (!dgt)
4690 dgt = &Dgt0_9_bcd;
4691
4692 return tvb_get_bcd_string(scope, tvb, offset, len, dgt, skip_first, false0, true1);
4693}
4694
4695/*
4696 * Format a bunch of data from a tvbuff as bytes, returning a pointer
4697 * to the string with the formatted data.
4698 */
4699char *tvb_bytes_to_str(wmem_allocator_t *allocator, tvbuff_t *tvb,
4700 const int offset, const int len)
4701{
4702 DISSECTOR_ASSERT(len >= 0)((void) ((len >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/tvbuff.c", 4702, "len >= 0"
))))
;
4703 return bytes_to_str(allocator, ensure_contiguous(tvb, offset, len), len)bytes_to_str_maxlen(allocator, ensure_contiguous(tvb, offset,
len), len, 36)
;
4704}
4705
4706/* Find a needle tvbuff within a haystack tvbuff. */
4707int
4708tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, const int haystack_offset)
4709{
4710 unsigned haystack_abs_offset = 0, haystack_abs_length = 0;
4711 const uint8_t *haystack_data;
4712 const uint8_t *needle_data;
4713 const unsigned needle_len = needle_tvb->length;
4714 const uint8_t *location;
4715
4716 DISSECTOR_ASSERT(haystack_tvb && haystack_tvb->initialized)((void) ((haystack_tvb && haystack_tvb->initialized
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/tvbuff.c", 4716, "haystack_tvb && haystack_tvb->initialized"
))))
;
4717
4718 if (haystack_tvb->length < 1 || needle_tvb->length < 1) {
4719 return -1;
4720 }
4721
4722 /* Get pointers to the tvbuffs' data. */
4723 haystack_data = ensure_contiguous(haystack_tvb, 0, -1);
4724 needle_data = ensure_contiguous(needle_tvb, 0, -1);
4725
4726 check_offset_length(haystack_tvb, haystack_offset, -1,
4727 &haystack_abs_offset, &haystack_abs_length);
4728
4729 location = ws_memmem(haystack_data + haystack_abs_offset, haystack_abs_length,
4730 needle_data, needle_len);
4731
4732 if (location) {
4733 return (int) (location - haystack_data);
4734 }
4735
4736 return -1;
4737}
4738
4739int
4740tvb_raw_offset(tvbuff_t *tvb)
4741{
4742 return ((tvb->raw_offset==-1) ? (tvb->raw_offset = tvb_offset_from_real_beginning(tvb)) : tvb->raw_offset);
4743}
4744
4745void
4746tvb_set_fragment(tvbuff_t *tvb)
4747{
4748 tvb->flags |= TVBUFF_FRAGMENT0x00000001;
4749}
4750
4751struct tvbuff *
4752tvb_get_ds_tvb(tvbuff_t *tvb)
4753{
4754 return(tvb->ds_tvb);
4755}
4756
4757unsigned
4758tvb_get_varint(tvbuff_t *tvb, unsigned offset, unsigned maxlen, uint64_t *value, const unsigned encoding)
4759{
4760 *value = 0;
4761
4762 switch (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
4763 case ENC_VARINT_PROTOBUF0x00000002:
4764 {
4765 unsigned i;
4766 uint64_t b; /* current byte */
4767
4768 for (i = 0; ((i < FT_VARINT_MAX_LEN10) && (i < maxlen)); ++i) {
4769 b = tvb_get_uint8(tvb, offset++);
4770 *value |= ((b & 0x7F) << (i * 7)); /* add lower 7 bits to val */
4771
4772 if (b < 0x80) {
4773 /* end successfully because of last byte's msb(most significant bit) is zero */
4774 return i + 1;
4775 }
4776 }
4777 break;
4778 }
4779
4780 case ENC_VARINT_ZIGZAG0x00000008:
4781 {
4782 unsigned i;
4783 uint64_t b; /* current byte */
4784
4785 for (i = 0; ((i < FT_VARINT_MAX_LEN10) && (i < maxlen)); ++i) {
4786 b = tvb_get_uint8(tvb, offset++);
4787 *value |= ((b & 0x7F) << (i * 7)); /* add lower 7 bits to val */
4788
4789 if (b < 0x80) {
4790 /* end successfully because of last byte's msb(most significant bit) is zero */
4791 *value = (*value >> 1) ^ ((*value & 1) ? -1 : 0);
4792 return i + 1;
4793 }
4794 }
4795 break;
4796 }
4797
4798 case ENC_VARINT_SDNV0x00000010:
4799 {
4800 /* Decodes similar to protobuf but in MSByte order */
4801 unsigned i;
4802 uint64_t b; /* current byte */
4803
4804 for (i = 0; ((i < FT_VARINT_MAX_LEN10) && (i < maxlen)); ++i) {
4805 b = tvb_get_uint8(tvb, offset++);
4806 if ((i == 9) && (*value >= UINT64_C(1)1UL<<(64-7))) {
4807 // guaranteed overflow, not valid SDNV
4808 return 0;
4809 }
4810 *value <<= 7;
4811 *value |= (b & 0x7F); /* add lower 7 bits to val */
4812
4813 if (b < 0x80) {
4814 /* end successfully because of last byte's msb(most significant bit) is zero */
4815 return i + 1;
4816 }
4817 }
4818 break;
4819 }
4820
4821 case ENC_VARINT_QUIC0x00000004:
4822 {
4823 /* calculate variable length */
4824 *value = tvb_get_uint8(tvb, offset);
4825 switch((*value) >> 6) {
4826 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
4827 (*value) &= 0x3F;
4828 return 1;
4829 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
4830 *value = tvb_get_ntohs(tvb, offset) & 0x3FFF;
4831 return 2;
4832 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
4833 *value = tvb_get_ntohl(tvb, offset) & 0x3FFFFFFF;
4834 return 4;
4835 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
4836 *value = tvb_get_ntoh64(tvb, offset) & UINT64_C(0x3FFFFFFFFFFFFFFF)0x3FFFFFFFFFFFFFFFUL;
4837 return 8;
4838 default: /* No Possible */
4839 ws_assert_not_reached()ws_log_fatal_full("", LOG_LEVEL_ERROR, "epan/tvbuff.c", 4839,
__func__, "assertion \"not reached\" failed")
;
4840 break;
4841 }
4842 break;
4843 }
4844
4845 default:
4846 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/tvbuff.c", 4846))
;
4847 }
4848
4849 return 0; /* 10 bytes scanned, but no bytes' msb is zero */
4850}
4851
4852/*
4853 * Editor modelines - https://www.wireshark.org/tools/modelines.html
4854 *
4855 * Local variables:
4856 * c-basic-offset: 8
4857 * tab-width: 8
4858 * indent-tabs-mode: t
4859 * End:
4860 *
4861 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
4862 * :indentSize=8:tabSize=8:noTabs=false:
4863 */