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:
Guy Harris 2019-06-12 17:26:52 -07:00
parent fb0d1ee24e
commit ce4a2816ff
3 changed files with 157 additions and 160 deletions

View File

@ -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
*

View File

@ -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

View File

@ -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;