#include "wsutil/unicode-utils.h"
#include "wsutil/nstime.h"
#include "wsutil/time_util.h"
-#include "wsutil/ws_mempbrk.h"
#include "tvbuff.h"
#include "tvbuff-int.h"
#include "strutil.h"
/* already aligned -> shortcut */
if ((left == 0) && (remaining_bits == 0)) {
- return tvb_new_subset(tvb, byte_offset, datalen, -1);
+ return tvb_new_subset(tvb, byte_offset, datalen, datalen);
}
DISSECTOR_ASSERT(datalen>0);
tvb_generic_clone_offset_len(tvbuff_t *tvb, guint offset, guint len)
{
tvbuff_t *cloned_tvb;
+ guint8 *data;
- guint8 *data = (guint8 *) g_malloc(len);
+ DISSECTOR_ASSERT(tvb_bytes_exist(tvb, offset, len));
+
+ data = (guint8 *) g_malloc(len);
tvb_memcpy(tvb, data, offset, len);
guint
tvb_ensure_captured_length_remaining(const tvbuff_t *tvb, const gint offset)
{
- guint abs_offset, rem_length;
+ guint abs_offset = 0, rem_length = 0;
int exception;
DISSECTOR_ASSERT(tvb && tvb->initialized);
static inline const guint8*
ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length, int *pexception)
{
- guint abs_offset, abs_length;
+ guint abs_offset = 0, abs_length = 0;
int exception;
exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length);
return NULL;
}
-static inline const guint8*
-guint8_pbrk(const guint8* haystack, size_t haystacklen, const guint8 *needles, guchar *found_needle)
-{
- const guint8 *result = ws_mempbrk(haystack, haystacklen, needles);
-
- if (result && found_needle)
- *found_needle = *result;
-
- return result;
-}
-
/************** ACCESSORS **************/
void *
tvb_memcpy(tvbuff_t *tvb, void *target, const gint offset, size_t length)
{
- guint abs_offset, abs_length;
+ guint abs_offset = 0, abs_length = 0;
DISSECTOR_ASSERT(tvb && tvb->initialized);
if (tvb->ops->tvb_memcpy)
return tvb->ops->tvb_memcpy(tvb, target, abs_offset, abs_length);
- /* XXX, fallback to slower method */
-
- DISSECTOR_ASSERT_NOT_REACHED();
+ /*
+ * If the length is 0, there's nothing to do.
+ * (tvb->real_data could be null if it's allocated with
+ * a size of length.)
+ */
+ if (length != 0) {
+ /*
+ * XXX, fallback to slower method
+ */
+ DISSECTOR_ASSERT_NOT_REACHED();
+ }
return NULL;
}
void *
tvb_memdup(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, size_t length)
{
- guint abs_offset, abs_length;
+ guint abs_offset = 0, abs_length = 0;
void *duped;
DISSECTOR_ASSERT(tvb && tvb->initialized);
return pntoh64(ptr);
}
+guint16
+tvb_get_guint16(tvbuff_t *tvb, const gint offset, const guint encoding) {
+ if (encoding & ENC_LITTLE_ENDIAN) {
+ return tvb_get_letohs(tvb, offset);
+ } else {
+ return tvb_get_ntohs(tvb, offset);
+ }
+}
+
+guint32
+tvb_get_guint24(tvbuff_t *tvb, const gint offset, const guint encoding) {
+ if (encoding & ENC_LITTLE_ENDIAN) {
+ return tvb_get_letoh24(tvb, offset);
+ } else {
+ return tvb_get_ntoh24(tvb, offset);
+ }
+}
+
+guint32
+tvb_get_guint32(tvbuff_t *tvb, const gint offset, const guint encoding) {
+ if (encoding & ENC_LITTLE_ENDIAN) {
+ return tvb_get_letohl(tvb, offset);
+ } else {
+ return tvb_get_ntohl(tvb, offset);
+ }
+}
+
+guint64
+tvb_get_guint40(tvbuff_t *tvb, const gint offset, const guint encoding) {
+ if (encoding & ENC_LITTLE_ENDIAN) {
+ return tvb_get_letoh40(tvb, offset);
+ } else {
+ return tvb_get_ntoh40(tvb, offset);
+ }
+}
+
+gint64
+tvb_get_gint40(tvbuff_t *tvb, const gint offset, const guint encoding) {
+ if (encoding & ENC_LITTLE_ENDIAN) {
+ return tvb_get_letohi40(tvb, offset);
+ } else {
+ return tvb_get_ntohi40(tvb, offset);
+ }
+}
+
+guint64
+tvb_get_guint48(tvbuff_t *tvb, const gint offset, const guint encoding) {
+ if (encoding & ENC_LITTLE_ENDIAN) {
+ return tvb_get_letoh48(tvb, offset);
+ } else {
+ return tvb_get_ntoh48(tvb, offset);
+ }
+}
+
+gint64
+tvb_get_gint48(tvbuff_t *tvb, const gint offset, const guint encoding) {
+ if (encoding & ENC_LITTLE_ENDIAN) {
+ return tvb_get_letohi48(tvb, offset);
+ } else {
+ return tvb_get_ntohi48(tvb, offset);
+ }
+}
+
+guint64
+tvb_get_guint56(tvbuff_t *tvb, const gint offset, const guint encoding) {
+ if (encoding & ENC_LITTLE_ENDIAN) {
+ return tvb_get_letoh56(tvb, offset);
+ } else {
+ return tvb_get_ntoh56(tvb, offset);
+ }
+}
+
+gint64
+tvb_get_gint56(tvbuff_t *tvb, const gint offset, const guint encoding) {
+ if (encoding & ENC_LITTLE_ENDIAN) {
+ return tvb_get_letohi56(tvb, offset);
+ } else {
+ return tvb_get_ntohi56(tvb, offset);
+ }
+}
+
+guint64
+tvb_get_guint64(tvbuff_t *tvb, const gint offset, const guint encoding) {
+ if (encoding & ENC_LITTLE_ENDIAN) {
+ return tvb_get_letoh64(tvb, offset);
+ } else {
+ return tvb_get_ntoh64(tvb, offset);
+ }
+}
+
+gfloat
+tvb_get_ieee_float(tvbuff_t *tvb, const gint offset, const guint encoding) {
+ if (encoding & ENC_LITTLE_ENDIAN) {
+ return tvb_get_letohieee_float(tvb, offset);
+ } else {
+ return tvb_get_ntohieee_float(tvb, offset);
+ }
+}
+
+gdouble
+tvb_get_ieee_double(tvbuff_t *tvb, const gint offset, const guint encoding) {
+ if (encoding & ENC_LITTLE_ENDIAN) {
+ return tvb_get_letohieee_double(tvb, offset);
+ } else {
+ return tvb_get_ntohieee_double(tvb, offset);
+ }
+}
+
/*
* Stuff for IEEE float handling on platforms that don't have IEEE
* format as the native floating-point format.
* NOTE: to support code written when proto_tree_add_item() took a
* gboolean as its last argument, with FALSE meaning "big-endian"
* and TRUE meaning "little-endian", we treat any non-zero value of
- * "representation" as meaning "little-endian".
+ * "encoding" as meaning "little-endian".
*/
void
-tvb_get_guid(tvbuff_t *tvb, const gint offset, e_guid_t *guid, const guint representation)
+tvb_get_guid(tvbuff_t *tvb, const gint offset, e_guid_t *guid, const guint encoding)
{
- if (representation) {
+ if (encoding) {
tvb_get_letohguid(tvb, offset, guid);
} else {
tvb_get_ntohguid(tvb, offset, guid);
tvb_find_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 needle)
{
const guint8 *result;
- guint abs_offset;
- guint limit;
+ guint abs_offset = 0;
+ guint limit = 0;
int exception;
DISSECTOR_ASSERT(tvb && tvb->initialized);
}
static inline gint
-tvb_pbrk_guint8_generic(tvbuff_t *tvb, guint abs_offset, guint limit, const guint8 *needles, guchar *found_needle)
+tvb_ws_mempbrk_guint8_generic(tvbuff_t *tvb, guint abs_offset, guint limit, const ws_mempbrk_pattern* pattern, guchar *found_needle)
{
const guint8 *ptr;
const guint8 *result;
ptr = ensure_contiguous(tvb, abs_offset, limit); /* tvb_get_ptr */
- result = guint8_pbrk(ptr, limit, needles, found_needle);
+ result = ws_mempbrk_exec(ptr, limit, pattern, found_needle);
if (!result)
return -1;
return (gint) ((result - ptr) + abs_offset);
}
-/* Find first occurrence of any of the needles in tvbuff, starting at offset.
+
+/* Find first occurrence of any of the pattern chars in tvbuff, starting at offset.
* Searches at most maxlength number of bytes; if maxlength is -1, searches
* to end of tvbuff.
* Returns the offset of the found needle, or -1 if not found.
* in that case, -1 will be returned if the boundary is reached before
* finding needle. */
gint
-tvb_pbrk_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 *needles, guchar *found_needle)
+tvb_ws_mempbrk_pattern_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength,
+ const ws_mempbrk_pattern* pattern, guchar *found_needle)
{
const guint8 *result;
- guint abs_offset;
- guint limit;
+ guint abs_offset = 0;
+ guint limit = 0;
int exception;
DISSECTOR_ASSERT(tvb && tvb->initialized);
/* If we have real data, perform our search now. */
if (tvb->real_data) {
- result = guint8_pbrk(tvb->real_data + abs_offset, limit, needles, found_needle);
+ result = ws_mempbrk_exec(tvb->real_data + abs_offset, limit, pattern, found_needle);
if (result == NULL) {
return -1;
}
}
}
- if (tvb->ops->tvb_pbrk_guint8)
- return tvb->ops->tvb_pbrk_guint8(tvb, abs_offset, limit, needles, found_needle);
+ if (tvb->ops->tvb_ws_mempbrk_pattern_guint8)
+ return tvb->ops->tvb_ws_mempbrk_pattern_guint8(tvb, abs_offset, limit, pattern, found_needle);
- return tvb_pbrk_guint8_generic(tvb, abs_offset, limit, needles, found_needle);
+ return tvb_ws_mempbrk_guint8_generic(tvb, abs_offset, limit, pattern, found_needle);
}
/* Find size of stringz (NUL-terminated string) by looking for terminating
guint
tvb_strsize(tvbuff_t *tvb, const gint offset)
{
- guint abs_offset, junk_length;
+ guint abs_offset = 0, junk_length;
gint nul_offset;
DISSECTOR_ASSERT(tvb && tvb->initialized);
tvb_strnlen(tvbuff_t *tvb, const gint offset, const guint maxlength)
{
gint result_offset;
- guint abs_offset, junk_length;
+ guint abs_offset = 0, junk_length;
DISSECTOR_ASSERT(tvb && tvb->initialized);
_tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer, gint *bytes_copied)
{
gint stringlen;
- guint abs_offset;
- gint limit, len;
+ guint abs_offset = 0;
+ gint limit, len = 0;
gboolean decreased_max = FALSE;
/* Only read to end of tvbuff, w/o throwing exception. */
}
}
+
+static ws_mempbrk_pattern pbrk_crlf;
/*
* Given a tvbuff, an offset into the tvbuff, and a length that starts
* at that offset (which may be -1 for "all the way to the end of the
gint
tvb_find_line_end(tvbuff_t *tvb, const gint offset, int len, gint *next_offset, const gboolean desegment)
{
-#ifdef WIN32
- static const char __declspec(align(16)) crlf[] = "\r\n" ;
-#else
- static const char crlf[] __attribute__((aligned(16))) = "\r\n" ;
-#endif
-
gint eob_offset;
gint eol_offset;
int linelen;
guchar found_needle = 0;
+ static gboolean compiled = FALSE;
DISSECTOR_ASSERT(tvb && tvb->initialized);
*/
eob_offset = offset + len;
+ if (!compiled) {
+ ws_mempbrk_compile(&pbrk_crlf, "\r\n");
+ compiled = TRUE;
+ }
+
/*
* Look either for a CR or an LF.
*/
- eol_offset = tvb_pbrk_guint8(tvb, offset, len, crlf, &found_needle);
+ eol_offset = tvb_ws_mempbrk_pattern_guint8(tvb, offset, len, &pbrk_crlf, &found_needle);
if (eol_offset == -1) {
/*
* No CR or LF - line is presumably continued in next packet.
return linelen;
}
+static ws_mempbrk_pattern pbrk_crlf_dquote;
/*
* Given a tvbuff, an offset into the tvbuff, and a length that starts
* at that offset (which may be -1 for "all the way to the end of the
guchar c = 0;
gint eob_offset;
int linelen;
+ static gboolean compiled = FALSE;
DISSECTOR_ASSERT(tvb && tvb->initialized);
if (len == -1)
len = _tvb_captured_length_remaining(tvb, offset);
+
+ if (!compiled) {
+ ws_mempbrk_compile(&pbrk_crlf_dquote, "\r\n\"");
+ compiled = TRUE;
+ }
+
/*
* XXX - what if "len" is still -1, meaning "offset is past the
* end of the tvbuff"?
/*
* Look either for a CR, an LF, or a '"'.
*/
- char_offset = tvb_pbrk_guint8(tvb, cur_offset, len, "\r\n\"", &c);
+ char_offset = tvb_ws_mempbrk_pattern_guint8(tvb, cur_offset, len, &pbrk_crlf_dquote, &c);
}
if (char_offset == -1) {
/*
* separator.
*/
gchar *
-tvb_bytes_to_ep_str_punct(tvbuff_t *tvb, const gint offset, const gint len, const gchar punct)
+tvb_bytes_to_str_punct(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, const gint len, const gchar punct)
{
- return bytes_to_ep_str_punct(ensure_contiguous(tvb, offset, len), len, punct);
+ return bytestring_to_str(scope, ensure_contiguous(tvb, offset, len), len, punct);
}
*/
octet = octet >> 4;
- if (octet == 0x0f) /* odd number bytes - hit filler */
+ if (t_offset == length - 1 && octet == 0x0f) {
+ /*
+ * This is the last octet, and the low-order
+ * nibble is 0xf, so we have an odd number of
+ * digits, and this is a filler digit. Ignore
+ * it.
+ */
break;
+ }
digit_str[i] = dgt->out[octet & 0x0f];
i++;
* Format a bunch of data from a tvbuff as bytes, returning a pointer
* to the string with the formatted data.
*/
-gchar *
-tvb_bytes_to_ep_str(tvbuff_t *tvb, const gint offset, const gint len)
+gchar *tvb_bytes_to_str(wmem_allocator_t *allocator, tvbuff_t *tvb,
+ const gint offset, const gint len)
{
- return bytes_to_ep_str(ensure_contiguous(tvb, offset, len), len);
+ return bytes_to_str(allocator, ensure_contiguous(tvb, offset, len), len);
}
/* Find a needle tvbuff within a haystack tvbuff. */
gint
tvb_find_tvb(tvbuff_t *haystack_tvb, tvbuff_t *needle_tvb, const gint haystack_offset)
{
- guint haystack_abs_offset, haystack_abs_length;
+ guint haystack_abs_offset = 0, haystack_abs_length = 0;
const guint8 *haystack_data;
const guint8 *needle_data;
const guint needle_len = needle_tvb->length;