forked from osmocom/wireshark
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>
This commit is contained in:
parent
fb0d1ee24e
commit
ce4a2816ff
|
@ -127,162 +127,6 @@ int dissect_ms_compressed_string(tvbuff_t *tvb, proto_tree *tree, int offset, in
|
|||
return offset + compr_len;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
|
|
|
@ -25,10 +25,6 @@ int display_ms_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index,
|
|||
int dissect_ms_compressed_string(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_index,
|
||||
const char **data);
|
||||
|
||||
const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
|
||||
gboolean useunicode, int *len, gboolean nopad, gboolean exactlen,
|
||||
guint16 *bcp);
|
||||
|
||||
extern const value_string share_type_vals[];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue