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):