diff options
-rw-r--r-- | doc/README.developer | 7 | ||||
-rw-r--r-- | epan/tvbuff.c | 68 | ||||
-rw-r--r-- | epan/tvbuff.h | 3 |
3 files changed, 78 insertions, 0 deletions
diff --git a/doc/README.developer b/doc/README.developer index 8f6c99d788..ed1c2ad921 100644 --- a/doc/README.developer +++ b/doc/README.developer @@ -1266,6 +1266,7 @@ file is opened. guint8 *tvb_get_stringz(tvbuff_t *tvb, gint offset, gint *lengthp); guint8 *tvb_get_ephemeral_stringz(tvbuff_t *tvb, gint offset, gint *lengthp); +gchar *tvb_get_ephemeral_unicode_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding); guint8 *tvb_get_seasonal_stringz(tvbuff_t *tvb, gint offset, gint *lengthp); Returns a null-terminated buffer, allocated with "g_malloc()", @@ -1277,11 +1278,17 @@ will be set to the length of the string, including the terminating null. tvb_get_stringz() returns a buffer allocated by g_malloc() so you must g_free() it when you are finished with the string. Failure to g_free() this buffer will lead to memory leaks. + tvb_get_ephemeral_stringz() returns a buffer allocated from a special heap with a lifetime until the next packet is dissected. You do not need to free() this buffer, it will happen automatically once the next packet is dissected. +tvb_get_ephemeral_unicode_stringz() is a unicode (UTF-16) version of +above. This is intended for reading UTF-16 unicode strings out of a tvbuff +and returning them as a UTF-8 string for use in Wireshark. The offset and +returned length pointer are in bytes, not UTF-16 characters. + tvb_get_seasonal_stringz() returns a buffer allocated from a special heap with a lifetime of the current capture session. You do not need to free() this buffer, it will happen automatically once the a new capture or diff --git a/epan/tvbuff.c b/epan/tvbuff.c index 29ab888fa0..c6bec158f4 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -1949,6 +1949,25 @@ tvb_strsize(tvbuff_t *tvb, const gint offset) return (nul_offset - abs_offset) + 1; } +/* Unicode (UTF-16) version of tvb_strsize */ +/* Returns number of *UTF-16 characters* (not bytes) excluding the null terminator */ +guint +tvb_unicode_strsize(tvbuff_t *tvb, const gint offset) +{ + guint i = 0; + gunichar2 uchar; + + DISSECTOR_ASSERT(tvb && tvb->initialized); + + do { + /* Endianness doesn't matter when looking for null */ + uchar = tvb_get_ntohs(tvb, offset + i); + i += 2; + } while(uchar != 0); + + return i; +} + /* Find length of string by looking for end of string ('\0'), up to * 'maxlength' characters'; if 'maxlength' is -1, searches to end * of tvbuff. @@ -2345,6 +2364,55 @@ tvb_get_ephemeral_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp) } /* + * Unicode (UTF-16) version of tvb_get_ephemeral_stringz() + * + * Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN + * + * Returns an ep_ allocated UTF-8 string + */ +gchar * +tvb_get_ephemeral_unicode_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding) +{ + gchar *tmpbuf = NULL; + gunichar2 uchar; + gint size; /* Number of UTF-16 characters */ + gint i; /* Byte counter for tvbuff */ + gint tmpbuf_len; + emem_strbuf_t *strbuf = NULL; + + strbuf = ep_strbuf_new(NULL); + + size = tvb_unicode_strsize(tvb, offset); + + for(i = 0; i < size; i += 2) { /* XXX - make <= ??? */ + + if(encoding == ENC_BIG_ENDIAN) + uchar = tvb_get_ntohs(tvb, offset + i); + else + uchar = tvb_get_letohs(tvb, offset + i); + + /* Calculate how much space is needed to store UTF-16 character in UTF-8 */ + tmpbuf_len = g_unichar_to_utf8(uchar, NULL); + + tmpbuf = g_malloc(tmpbuf_len + 1); /* + 1 to make room for null terminator */ + + g_unichar_to_utf8(uchar, tmpbuf); + + /* NULL terminate the tmpbuf so ep_strbuf_append knows where to stop */ + tmpbuf[tmpbuf_len] = '\0'; + + ep_strbuf_append(strbuf, tmpbuf); + + g_free(tmpbuf); + } + + if(lengthp) + *lengthp = i; + + return strbuf->str; +} + +/* * Given a tvbuff and an offset, with the offset assumed to refer to * a null-terminated string, find the length of that string (and throw * an exception if the tvbuff ends before we find the null), allocate diff --git a/epan/tvbuff.h b/epan/tvbuff.h index 8d5b443eb1..d4e76230a9 100644 --- a/epan/tvbuff.h +++ b/epan/tvbuff.h @@ -515,12 +515,15 @@ extern guint8 *tvb_get_seasonal_string(tvbuff_t *tvb, const gint offset, const g * instead it will automatically be freed once the next * packet is dissected. * + * tvb_get_ephemeral_unicode_stringz() Unicode (UTF-16) version of above + * * tvb_get_seasonal_stringz() returns a string that does not need to be freed, * instead it will automatically be freed when a new capture * or file is opened. */ extern guint8 *tvb_get_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp); extern guint8 *tvb_get_ephemeral_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp); +extern gchar *tvb_get_ephemeral_unicode_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding); extern guint8 *tvb_get_seasonal_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp); /** Looks for a stringz (NUL-terminated string) in tvbuff and copies |