aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-smb.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2019-06-12 17:26:52 -0700
committerGuy Harris <guy@alum.mit.edu>2019-06-13 01:44:02 +0000
commitce4a2816ff66ae5a7cf45fec10ac85fcbb66cef9 (patch)
tree532dc1858fc8f4553be2c47b96615fd828568b4a /epan/dissectors/packet-smb.c
parentfb0d1ee24edeed29baac1bdb053d1553580d431c (diff)
Pull get_unicode_or_ascii_string() into packet-smb.c.
Nobody else needs its extra stuff, as they're not pulling data out of an SMB byte buffer, so they don't need the extra length check, and nobody else uses it - or should use it, as we now have support for string encodings in the tvbuff and protocol-tree code. Change-Id: I8d249ea2c89a744eef12a05ad755811c07ca463a Reviewed-on: https://code.wireshark.org/review/33581 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/dissectors/packet-smb.c')
-rw-r--r--epan/dissectors/packet-smb.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/epan/dissectors/packet-smb.c b/epan/dissectors/packet-smb.c
index b2a9c98c88..6d0fc69f63 100644
--- a/epan/dissectors/packet-smb.c
+++ b/epan/dissectors/packet-smb.c
@@ -1718,7 +1718,164 @@ static GSList *conv_tables = NULL;
End of request/response matching functions
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+/* Max string length for displaying Unicode strings. */
+#define MAX_UNICODE_STR_LEN 256
+
+/* Turn a little-endian Unicode '\0'-terminated string into a string we
+ can display.
+ XXX - for now, we just handle the ISO 8859-1 characters.
+ If exactlen==TRUE then us_lenp contains the exact len of the string in
+ bytes. It might not be null terminated !
+ bc specifies the number of bytes in the byte parameters; Windows 2000,
+ at least, appears, in some cases, to put only 1 byte of 0 at the end
+ of a Unicode string if the byte count
+*/
+static gchar *
+unicode_to_str(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen,
+ guint16 bc)
+{
+ gchar *cur;
+ gchar *p;
+ guint16 uchar;
+ int len;
+ int us_len;
+ gboolean overflow = FALSE;
+
+ cur=(gchar *)wmem_alloc(wmem_packet_scope(), MAX_UNICODE_STR_LEN+3+1);
+ p = cur;
+ len = MAX_UNICODE_STR_LEN;
+ us_len = 0;
+ for (;;) {
+ if (bc == 0)
+ break;
+
+ if (bc == 1) {
+ /* XXX - explain this */
+ if (!exactlen)
+ us_len += 1; /* this is a one-byte null terminator */
+ break;
+ }
+
+ uchar = tvb_get_letohs(tvb, offset);
+ if (uchar == 0) {
+ us_len += 2; /* this is a two-byte null terminator */
+ break;
+ }
+ if (len > 0) {
+ if ((uchar & 0xFF00) == 0)
+ *p++ = (gchar) uchar; /* ISO 8859-1 */
+ else
+ *p++ = '?'; /* not 8859-1 */
+ len--;
+ } else
+ overflow = TRUE;
+
+ offset += 2;
+ bc -= 2;
+ us_len += 2;
+
+ if(exactlen){
+ if(us_len>= *us_lenp){
+ break;
+ }
+ }
+ }
+ if (overflow) {
+ /* Note that we're not showing the full string. */
+ *p++ = '.';
+ *p++ = '.';
+ *p++ = '.';
+ }
+
+ *p = '\0';
+ *us_lenp = us_len;
+
+ return cur;
+}
+
+/* nopad == TRUE : Do not add any padding before this string
+ * exactlen == TRUE : len contains the exact len of the string in bytes.
+ * bc: pointer to variable with amount of data left in the byte parameters
+ * region
+ */
+const gchar *
+get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
+ gboolean useunicode, int *len, gboolean nopad, gboolean exactlen,
+ guint16 *bcp)
+{
+ gchar *cur;
+ const gchar *string;
+ int string_len = 0;
+ int copylen;
+ gboolean overflow = FALSE;
+
+ if (*bcp == 0) {
+ /* Not enough data in buffer */
+ return NULL;
+ }
+
+ if (useunicode) {
+ if ((!nopad) && (*offsetp % 2)) {
+ (*offsetp)++; /* Looks like a pad byte there sometimes */
+ (*bcp)--;
+
+ if (*bcp == 0) {
+ /* Not enough data in buffer */
+ return NULL;
+ }
+ }
+
+ if(exactlen){
+ string_len = *len;
+ if (string_len < 0) {
+ /* This probably means it's a very large unsigned number; just set
+ it to the largest signed number, so that we throw the appropriate
+ exception. */
+ string_len = INT_MAX;
+ }
+ }
+
+ string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
+
+ } else {
+ if(exactlen){
+ /*
+ * The string we return must be null-terminated.
+ */
+ cur=(gchar *)wmem_alloc(wmem_packet_scope(), MAX_UNICODE_STR_LEN+3+1);
+ copylen = *len;
+
+ if (copylen < 0) {
+ /* This probably means it's a very large unsigned number; just set
+ it to the largest signed number, so that we throw the appropriate
+ exception. */
+ copylen = INT_MAX;
+ }
+
+ tvb_ensure_bytes_exist(tvb, *offsetp, copylen);
+
+ if (copylen > MAX_UNICODE_STR_LEN) {
+ copylen = MAX_UNICODE_STR_LEN;
+ overflow = TRUE;
+ }
+
+ tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen);
+ cur[copylen] = '\0';
+
+ if (overflow)
+ g_strlcat(cur, "...",MAX_UNICODE_STR_LEN+3+1);
+
+ string_len = *len;
+ string = cur;
+ } else {
+ string = tvb_get_const_stringz(tvb, *offsetp, &string_len);
+ }
+ }
+
+ *len = string_len;
+ return string;
+}
typedef struct _smb_uid_t {
char *domain;