Wireshark-dev: Re: [Wireshark-dev] g_snprintf() and sizeof
From: Jakub Zawadzki <darkjames@xxxxxxxxxxxxxxxx>
Date: Sun, 22 Mar 2009 21:19:39 +0100
On Thu, Mar 19, 2009 at 08:06:55PM +0100, Jakub Zawadzki wrote: > On Thu, Mar 19, 2009 at 11:12:03AM -0700, Guy Harris wrote: > > Warning: g_snprintf()'s function signature has an annoying botch in it > > - the size argument is a gulong, not a gsize. > > > > Not a problem in the UN*X and Windows ILP32 environment and in the > > UN*X LP64 environment, but it causes the Microsoft compiler to > > (correctly) warn about a conversion from a 64-bit integer to a 32-bit > > integer in the Windows LLP64 environment. > > Cast sizeof - or any other size_t value - to (gulong) before passing it > > as the length argument to g_snprintf(). > > What do you think about creating ws_snprintf() & ws_vsnprintf() macros, > which would care about casting size to (gulong) ? In attachment possible fixup, (I've also changed some g_snprintf() to g_strlcat()) Could you review? Cheers
Index: wsutil/str_util.h
===================================================================
--- wsutil/str_util.h (wersja 27821)
+++ wsutil/str_util.h (kopia robocza)
@@ -25,6 +25,8 @@
#ifndef __STR_UTIL_H__
#define __STR_UTIL_H__
+#define ws_sncatprintf(str, size, ...) g_snprintf(str+strlen(str), (gulong) size-strlen(str), __VA_ARGS__)
+
/** Convert all upper-case ASCII letters to their ASCII lower-case
* equivalents, in place, with a simple non-locale-dependent
* ASCII mapping (A-Z -> a-z).
Index: epan/dissectors/packet-rtps.c
===================================================================
--- epan/dissectors/packet-rtps.c (wersja 27821)
+++ epan/dissectors/packet-rtps.c (kopia robocza)
@@ -60,6 +60,7 @@
#include <glib.h>
#include <epan/packet.h>
#include <epan/addr_resolv.h>
+#include <wsutil/str_util.h>
#include "packet-rtps.h"
@@ -2624,8 +2625,7 @@
dim_str[0] = '\0';
for (i = 0; i < MAX_ARRAY_DIMENSION; ++i) {
if (arr_dimension[i] != 0) {
- g_snprintf(dim_str+strlen(dim_str),
- 40-strlen(dim_str),
+ ws_sncatprintf(dim_str, sizeof(dim_str),
"[%d]", arr_dimension[i]);
} else {
break;
@@ -4239,8 +4239,7 @@
buffer[0] = '\0';
while (param_length >= 4) {
manager_key = NEXT_guint32(tvb, offset, little_endian);
- g_snprintf(buffer+strlen(buffer),
- MAX_PARAM_SIZE-strlen(buffer),
+ ws_sncatprintf(buffer, MAX_PARAM_SIZE,
"%c 0x%08x",
sep,
manager_key);
@@ -5915,8 +5914,7 @@
}
/*
if (smcr_ptr->counter > 1) {
- g_snprintf(info_buf+strlen(info_buf),
- MAX_SUMMARY_SIZE-strlen(info_buf),
+ ws_sncatprintf(info_buf, MAX_SUMMARY_SIZE,
"%s(%d)",
val_to_str(smcr_ptr->id,
submessage_id_vals,
@@ -5924,17 +5922,14 @@
smcr_ptr->counter);
} else {
*/
- g_snprintf(info_buf+strlen(info_buf),
- MAX_SUMMARY_SIZE-strlen(info_buf),
+ ws_sncatprintf(info_buf, MAX_SUMMARY_SIZE,
"%s%s",
val_to_str(smcr_ptr->id,
submessage_id_vals,
"Unknown[%02x]"),
smcr_ptr->extra ? smcr_ptr->extra : "");
if (strlen(info_buf) > (MAX_SUMMARY_SIZE - 20)) {
- g_snprintf(info_buf+strlen(info_buf),
- MAX_SUMMARY_SIZE-strlen(info_buf),
- "...");
+ g_strlcat(info_buf, "...", MAX_SUMMARY_SIZE);
break;
}
/*
Index: epan/dissectors/packet-enttec.c
===================================================================
--- epan/dissectors/packet-enttec.c (wersja 27821)
+++ epan/dissectors/packet-enttec.c (kopia robocza)
@@ -39,6 +39,7 @@
#include <epan/addr_resolv.h>
#include <epan/prefs.h>
#include <epan/strutil.h>
+#include <wsutil/str_util.h>
/*
* See
@@ -204,7 +205,6 @@
guint16 length,r,c,row_count;
guint8 v,type,count;
guint16 ci,ui,i,start_offset,end_offset;
- char* ptr;
proto_tree_add_item(tree, hf_enttec_dmx_data_universe, tvb,
offset, 1, FALSE);
@@ -279,29 +279,23 @@
si = proto_item_add_subtree(hi, ett_enttec);
row_count = (ui/global_disp_col_count) + ((ui%global_disp_col_count) == 0 ? 0 : 1);
- ptr = string;
- /* XX: In theory the g_snprintf statements below could store '\0' bytes off the end of the */
- /* 'string' buffer'. This is so since g_snprint returns the number of characters which */
- /* "would have been written" (whether or not there was room) and since ptr is always */
- /* incremented by this amount. In practice the string buffer is large enough such that the */
- /* string buffer size is not exceeded even with the maximum number of columns which might */
- /* be displayed. */
- /* ToDo: consider recoding slightly ... */
for (r=0; r < row_count;r++) {
+ string[0] = '\0';
+
for (c=0;(c < global_disp_col_count) && (((r*global_disp_col_count)+c) < ui);c++) {
if ((c % (global_disp_col_count/2)) == 0) {
- ptr += g_snprintf(ptr, sizeof string - strlen(string), " ");
+ g_strlcat(string, " ", sizeof(string));
}
v = dmx_data[(r*global_disp_col_count)+c];
if (global_disp_chan_val_type == 0) {
v = (v * 100) / 255;
if (v == 100) {
- ptr += g_snprintf(ptr, sizeof string - strlen(string), "FL ");
+ g_strlcat(string, "FL ", sizeof(string));
} else {
- ptr += g_snprintf(ptr, sizeof string - strlen(string), chan_format[global_disp_chan_val_type], v);
+ ws_sncatprintf(string, sizeof(string), chan_format[global_disp_chan_val_type], v);
}
} else {
- ptr += g_snprintf(ptr, sizeof string - strlen(string), chan_format[global_disp_chan_val_type], v);
+ ws_sncatprintf(string, sizeof(string), chan_format[global_disp_chan_val_type], v);
}
}
@@ -312,7 +306,6 @@
offset+start_offset,
end_offset-start_offset,
string_format[global_disp_chan_nr_type], (r*global_disp_col_count)+1, string);
- ptr = string;
}
item = proto_tree_add_item(si, hf_enttec_dmx_data_data_filter, tvb,
Index: epan/dissectors/packet-rtps2.c
===================================================================
--- epan/dissectors/packet-rtps2.c (wersja 27821)
+++ epan/dissectors/packet-rtps2.c (kopia robocza)
@@ -56,6 +56,7 @@
#include <epan/packet.h>
#include <epan/addr_resolv.h>
#include <epan/prefs.h>
+#include <wsutil/str_util.h>
#include "packet-rtps2.h"
@@ -2898,8 +2899,7 @@
dim_str[0] = '\0';
for (i = 0; i < MAX_ARRAY_DIMENSION; ++i) {
if (arr_dimension[i] != 0) {
- g_snprintf(dim_str+strlen(dim_str),
- 40-strlen(dim_str),
+ ws_sncatprintf(dim_str, sizeof(dim_str),
"[%d]", arr_dimension[i]);
} else {
break;
@@ -3698,10 +3698,10 @@
ett_rtps_entity,
"guidSuffix",
NULL);
- memset(buffer, 0, MAX_PARAM_SIZE);
+ buffer[0] = '\0';
for (i = 0; i < 16; ++i) {
guidPart = tvb_get_guint8(tvb, offset+i);
- g_snprintf(buffer+strlen(buffer), MAX_PARAM_SIZE-strlen(buffer),
+ ws_sncatprintf(buffer, MAX_PARAM_SIZE,
"%02x", guidPart);
if (i == 3 || i == 7 || i == 11) g_strlcat(buffer, ":", MAX_PARAM_SIZE);
}
@@ -3730,7 +3730,7 @@
g_strlcat(buffer, "guid: ", MAX_PARAM_SIZE);
for (i = 0; i < param_length; ++i) {
guidPart = tvb_get_guint8(tvb, offset+i);
- g_snprintf(buffer+strlen(buffer), MAX_PARAM_SIZE-strlen(buffer),
+ ws_sncatprintf(buffer, MAX_PARAM_SIZE,
"%02x", guidPart);
if (( ((i+1) % 4) == 0 ) && (i != param_length-1) )
g_strlcat(buffer, ":", MAX_PARAM_SIZE);
@@ -5115,8 +5115,7 @@
buffer[0] = '\0';
while (param_length >= 4) {
manager_key = NEXT_guint32(tvb, offset, little_endian);
- g_snprintf(buffer+strlen(buffer),
- MAX_PARAM_SIZE-strlen(buffer),
+ ws_sncatprintf(buffer, MAX_PARAM_SIZE,
"%c 0x%08x",
sep,
manager_key);
Index: epan/dissectors/packet-pim.c
===================================================================
--- epan/dissectors/packet-pim.c (wersja 27821)
+++ epan/dissectors/packet-pim.c (kopia robocza)
@@ -36,6 +36,8 @@
#include <epan/afn.h>
#include "packet-ipv6.h"
#include <epan/in_cksum.h>
+#include <wsutil/str_util.h>
+
#include "packet-pim.h"
#define PIM_TYPE(x) ((x) & 0x0f)
@@ -77,7 +79,7 @@
flags_masklen & 0x0040 ? "R" : "");
} else
buf[0] = '\0';
- g_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s/%u",
+ ws_sncatprintf(buf, sizeof(buf), "%s/%u",
ip_to_str(tvb_get_ptr(tvb, offset + 2, 4)), flags_masklen & 0x3f);
return buf;
@@ -566,7 +568,7 @@
break;
}
if (flags) {
- g_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ ws_sncatprintf(buf, sizeof(buf),
" (%s%s%s)",
flags & 0x04 ? "S" : "",
flags & 0x02 ? "W" : "",
Index: epan/dissectors/packet-iec104.c
===================================================================
--- epan/dissectors/packet-iec104.c (wersja 27821)
+++ epan/dissectors/packet-iec104.c (kopia robocza)
@@ -37,6 +37,7 @@
#include <epan/packet.h>
#include <epan/dissectors/packet-tcp.h>
#include <epan/emem.h>
+#include <wsutil/str_util.h>
/* IEC-104 comment: Fields are little endian. */
@@ -474,11 +475,11 @@
Bytex = val_to_strlen(asduh->TNCause & F_CAUSE, causetx_types);
for (Ind=Bytex; Ind< 7; Ind++) g_strlcat(res, " ", MAXS);
}
- g_snprintf(res+strlen(res), MAXS-strlen(res), " IOA=%d", asduh->IOA);
+ ws_sncatprintf(res, MAXS, " IOA=%d", asduh->IOA);
if (asduh->NumIx > 1) {
- if (asduh->SQ == F_SQ) g_snprintf(res+strlen(res), MAXS-strlen(res), "-%d", asduh->IOA+ asduh->NumIx- 1);
+ if (asduh->SQ == F_SQ) ws_sncatprintf(res, MAXS, "-%d", asduh->IOA+ asduh->NumIx- 1);
else g_strlcat(res, ",...", MAXS);
- g_snprintf(res+strlen(res), MAXS-strlen(res), " (%u)", asduh->NumIx);
+ ws_sncatprintf(res, MAXS, " (%u)", asduh->NumIx);
}
}
else {
@@ -587,24 +588,25 @@
if (Brossa != TcpLen) {
if (apcih->ApduLen <= APDU_MAX_LEN) {
/* APCI in 'Paquet List' */
- g_snprintf(res+strlen(res), MAXS-strlen(res), "%s%s(", pinfo->srcport == iec104port ? "->" : "<-", val_to_str(apcih->Type, apci_types, "<ERR>"));
+ ws_sncatprintf(res, MAXS, "%s%s(", pinfo->srcport == iec104port ? "->" : "<-", val_to_str(apcih->Type, apci_types, "<ERR>"));
switch(apcih->Type) { /* APCI in 'Packet List' */
case I_TYPE:
- g_snprintf(res+strlen(res), MAXS-strlen(res), "%d,", apcih->Tx);
+ ws_sncatprintf(res, MAXS, "%d,", apcih->Tx);
case S_TYPE:
- g_snprintf(res+strlen(res), MAXS-strlen(res), "%d)", apcih->Rx);
+ ws_sncatprintf(res, MAXS, "%d)", apcih->Rx);
/* Align first packets */
if (apcih->Tx < 10) g_strlcat(res, " ", MAXS);
if (apcih->Rx < 10) g_strlcat(res, " ", MAXS);
break;
case U_TYPE:
- g_snprintf(res+strlen(res), MAXS-strlen(res), "%s)", val_to_str(apcih->UType >> 2, u_types, "<ERR>"));
+ ws_sncatprintf(res, MAXS, "%s)", val_to_str(apcih->UType >> 2, u_types, "<ERR>"));
break;
}
- if (apcih->Type != I_TYPE && apcih->ApduLen > APDU_MIN_LEN) g_snprintf(res+strlen(res), MAXS-strlen(res), "<ERR %u bytes> ", apcih->ApduLen- APDU_MIN_LEN);
+ if (apcih->Type != I_TYPE && apcih->ApduLen > APDU_MIN_LEN)
+ ws_sncatprintf(res, MAXS, "<ERR %u bytes> ", apcih->ApduLen- APDU_MIN_LEN);
}
else {
- g_snprintf(res+strlen(res), MAXS-strlen(res), "<ERR ApduLen=%u bytes> ", apcih->ApduLen);
+ ws_sncatprintf(res, MAXS, "<ERR ApduLen=%u bytes> ", apcih->ApduLen);
}
}
g_strlcat(res, " ", MAXS); /* We add an space to separate possible APCIs/ASDUs in the same packet */
Index: epan/dissectors/packet-artnet.c
===================================================================
--- epan/dissectors/packet-artnet.c (wersja 27821)
+++ epan/dissectors/packet-artnet.c (kopia robocza)
@@ -39,6 +39,7 @@
#include <epan/addr_resolv.h>
#include <epan/prefs.h>
#include <epan/strutil.h>
+#include <wsutil/str_util.h>
/*
* See
@@ -757,7 +758,6 @@
guint16 length,r,c,row_count;
guint8 v;
static char string[255];
- char* ptr;
const char* chan_format[] = {
"%2u ",
"%02x ",
@@ -795,37 +795,31 @@
si = proto_item_add_subtree(hi, ett_artnet);
row_count = (length/global_disp_col_count) + ((length%global_disp_col_count) == 0 ? 0 : 1);
- ptr = string;
- /* XX: In theory the g_snprintf statements below could store '\0' bytes off the end of the */
- /* 'string' buffer'. This is so since g_snprint returns the number of characters which */
- /* "would have been written" (whether or not there was room) and since ptr is always */
- /* incremented by this amount. In practice the string buffer is large enough such that the */
- /* string buffer size is not exceeded even with the maximum number of columns which might */
- /* be displayed. */
- /* ToDo: consider recoding slightly ... */
+
for (r=0; r < row_count;r++) {
+ string[0] = '\0';
+
for (c=0;(c < global_disp_col_count) && (((r*global_disp_col_count)+c) < length);c++) {
if ((c % (global_disp_col_count/2)) == 0) {
- ptr += g_snprintf(ptr, (gulong)(sizeof string - strlen(string)), " ");
+ g_strlcat(string, " ", sizeof(string));
}
v = tvb_get_guint8(tvb, (offset+(r*global_disp_col_count)+c));
if (global_disp_chan_val_type == 0) {
v = (v * 100) / 255;
if (v == 100) {
- ptr += g_snprintf(ptr, (gulong)(sizeof string - strlen(string)), "FL ");
+ g_strlcat(string, "FL ", sizeof(string));
} else {
- ptr += g_snprintf(ptr, (gulong)(sizeof string - strlen(string)), chan_format[global_disp_chan_val_type], v);
+ ws_sncatprintf(string, sizeof(string), chan_format[global_disp_chan_val_type], v);
}
} else {
- ptr += g_snprintf(ptr, (gulong)(sizeof string - strlen(string)), chan_format[global_disp_chan_val_type], v);
+ ws_sncatprintf(string, sizeof(string), chan_format[global_disp_chan_val_type], v);
}
}
proto_tree_add_none_format(si,hf_artnet_output_dmx_data, tvb,
offset+(r*global_disp_col_count), c,
string_format[global_disp_chan_nr_type], (r*global_disp_col_count)+1, string);
- ptr = string;
}
/* Add the real type hidden */
- References:
- [Wireshark-dev] g_snprintf() and sizeof
- From: Guy Harris
- Re: [Wireshark-dev] g_snprintf() and sizeof
- From: Jakub Zawadzki
- [Wireshark-dev] g_snprintf() and sizeof
- Prev by Date: Re: [Wireshark-dev] complie fail on WinXP 32bit
- Next by Date: Re: [Wireshark-dev] Unable to Display Simple Protocol Tree
- Previous by thread: Re: [Wireshark-dev] g_snprintf() and sizeof
- Next by thread: Re: [Wireshark-dev] g_snprintf() and sizeof
- Index(es):