diff options
author | Peter Wu <peter@lekensteyn.nl> | 2014-07-06 15:34:38 +0200 |
---|---|---|
committer | Evan Huus <eapache@gmail.com> | 2014-07-06 23:00:40 +0000 |
commit | f2b4daf4005d60eef7e34e2e6ebf4fe487d3c255 (patch) | |
tree | 1fac15d7bcbc381c5e0a3a6602e7edd20e574e39 /epan | |
parent | ec6a22dc3ba8e2d438b34d892d6a40e1be2a28f2 (diff) |
Add printf-format annotations, fix garbage
The WRETH dissector showed up some garbage in the column display. Upon
further inspection, it turns out that the format string had a trailing
percent sign which caused (unsigned)-1 to be returned by
g_printf_string_upper_bound (in emem_strdup_vprintf). Then ep_alloc is
called with (unsigned)-1 + 1 = 0 memory, no wonder that garbage shows
up. ASAN could not even catch this error because EP is in charge of
this.
So, start adding G_GNUC_PRINTF annotations in each header that uses
the "fmt" or "format" paramters (grepped + awk). This revealed some
other errors. The NCP2222 dissector was missing a format string (not
a security vuln though).
Many dissectors used val_to_str with a constant (but empty) string,
these have been replaced by val_to_str_const. ASN.1 dissectors
were regenerated for this.
Minor: the mate plugin used "%X" instead of "%p" for a pointer type.
The ncp2222 dissector and wimax plugin gained modelines.
Change-Id: I7f3f6a3136116f9b251719830a39a7b21646f622
Reviewed-on: https://code.wireshark.org/review/2881
Reviewed-by: Evan Huus <eapache@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dfilter/dfilter-int.h | 2 | ||||
-rw-r--r-- | epan/dfilter/grammar.lemon | 4 | ||||
-rw-r--r-- | epan/dfilter/semcheck.c | 10 | ||||
-rw-r--r-- | epan/diam_dict.l | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-dis.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-h450-ros.c | 8 | ||||
-rw-r--r-- | epan/dissectors/packet-lisp.c | 8 | ||||
-rw-r--r-- | epan/dissectors/packet-ncp2222.inc | 14 | ||||
-rw-r--r-- | epan/dissectors/packet-q932-ros.c | 8 | ||||
-rw-r--r-- | epan/dissectors/packet-wreth.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-x509if.c | 6 | ||||
-rw-r--r-- | epan/dissectors/packet-zbee-aps.c | 2 | ||||
-rw-r--r-- | epan/emem.h | 5 | ||||
-rw-r--r-- | epan/except.h | 3 | ||||
-rw-r--r-- | epan/proto.h | 3 | ||||
-rw-r--r-- | epan/ptvcursor.h | 3 | ||||
-rw-r--r-- | epan/to_str.h | 2 | ||||
-rw-r--r-- | epan/value_string.h | 15 |
18 files changed, 61 insertions, 38 deletions
diff --git a/epan/dfilter/dfilter-int.h b/epan/dfilter/dfilter-int.h index 1b1018e7ad..8a7511de05 100644 --- a/epan/dfilter/dfilter-int.h +++ b/epan/dfilter/dfilter-int.h @@ -68,7 +68,7 @@ extern stnode_t *df_lval; /* Set dfilter_error_msg_buf and dfilter_error_msg */ void -dfilter_fail(const char *format, ...); +dfilter_fail(const char *format, ...) G_GNUC_PRINTF(1, 2); void DfilterTrace(FILE *TraceFILE, char *zTracePrompt); diff --git a/epan/dfilter/grammar.lemon b/epan/dfilter/grammar.lemon index 84803cd393..a9856127e6 100644 --- a/epan/dfilter/grammar.lemon +++ b/epan/dfilter/grammar.lemon @@ -81,11 +81,11 @@ any "error" symbols are shifted, if possible. */ break; case STTYPE_STRING: dfilter_fail("The string \"%s\" was unexpected in this context.", - stnode_data(TOKEN)); + (char *)stnode_data(TOKEN)); break; case STTYPE_UNPARSED: dfilter_fail("\"%s\" was unexpected in this context.", - stnode_data(TOKEN)); + (char *)stnode_data(TOKEN)); break; case STTYPE_INTEGER: dfilter_fail("The integer %d was unexpected in this context.", diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index c76859dc28..8e1d9b5bf6 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -358,7 +358,7 @@ check_exists(stnode_t *st_arg1) case STTYPE_STRING: case STTYPE_UNPARSED: dfilter_fail("\"%s\" is neither a field nor a protocol name.", - stnode_data(st_arg1)); + (char *)stnode_data(st_arg1)); THROW(TypeError); break; @@ -730,8 +730,8 @@ check_relation_LHS_STRING(const char* relation_string, else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) { /* Well now that's silly... */ dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.", - stnode_data(st_arg1), - stnode_data(st_arg2)); + (char *)stnode_data(st_arg1), + (char *)stnode_data(st_arg2)); THROW(TypeError); } else if (type2 == STTYPE_RANGE) { @@ -819,8 +819,8 @@ check_relation_LHS_UNPARSED(const char* relation_string, else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED) { /* Well now that's silly... */ dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.", - stnode_data(st_arg1), - stnode_data(st_arg2)); + (char *)stnode_data(st_arg1), + (char *)stnode_data(st_arg2)); THROW(TypeError); } else if (type2 == STTYPE_RANGE) { diff --git a/epan/diam_dict.l b/epan/diam_dict.l index 9615582681..730c02652c 100644 --- a/epan/diam_dict.l +++ b/epan/diam_dict.l @@ -111,7 +111,7 @@ static ddict_xmlpi_t* last_xmlpi; static char** attr_str; static unsigned* attr_uint; -static void ddict_debug(const char* fmt, ...); +static void ddict_debug(const char* fmt, ...) G_GNUC_PRINTF(1, 2); static void append_to_buffer(const char* txt, unsigned len); static FILE* ddict_open(const char*, const char*); diff --git a/epan/dissectors/packet-dis.c b/epan/dissectors/packet-dis.c index 2e1aa051b1..4a9723eed2 100644 --- a/epan/dissectors/packet-dis.c +++ b/epan/dissectors/packet-dis.c @@ -5125,7 +5125,7 @@ static int dissect_DIS_PARSER_SIGNAL_PDU(tvbuff_t *tvb, packet_info *pinfo, prot offset = parse_DIS_FIELDS_SIGNAL_LINK16_NETWORK_HEADER(tvb, tree, offset, &messageType); ti = proto_tree_add_text(tree, tvb, offset, -1, "Link 16 Message Data: %s", - val_to_str(messageType, DIS_PDU_Link16_MessageType_Strings, "")); + val_to_str_const(messageType, DIS_PDU_Link16_MessageType_Strings, "")); sub_tree = proto_item_add_subtree(ti, ett_dis_signal_link16_message_data); offset = parse_Link16_Message_Data(sub_tree, tvb, offset, pinfo, encodingScheme, messageType); proto_item_set_end(ti, tvb, offset); diff --git a/epan/dissectors/packet-h450-ros.c b/epan/dissectors/packet-h450-ros.c index 3a3dee4676..b12841ae30 100644 --- a/epan/dissectors/packet-h450-ros.c +++ b/epan/dissectors/packet-h450-ros.c @@ -422,7 +422,7 @@ dissect_h450_ros_GeneralProblem(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *a offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, &problem_val); #line 50 "../../asn1/h450-ros/h450-ros.cnf" - g_strlcpy(problem_str, val_to_str(problem_val, VALS(h450_ros_GeneralProblem_vals), ""), 64); + g_strlcpy(problem_str, val_to_str_const(problem_val, VALS(h450_ros_GeneralProblem_vals), ""), 64); problem_str[64-1] = '\0'; return offset; @@ -447,7 +447,7 @@ dissect_h450_ros_InvokeProblem(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *ac offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, &problem_val); #line 53 "../../asn1/h450-ros/h450-ros.cnf" - g_strlcpy(problem_str, val_to_str(problem_val, VALS(h450_ros_InvokeProblem_vals), ""), 64); + g_strlcpy(problem_str, val_to_str_const(problem_val, VALS(h450_ros_InvokeProblem_vals), ""), 64); problem_str[64-1] = '\0'; return offset; @@ -467,7 +467,7 @@ dissect_h450_ros_ReturnResultProblem(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, &problem_val); #line 56 "../../asn1/h450-ros/h450-ros.cnf" - g_strlcpy(problem_str, val_to_str(problem_val, VALS(h450_ros_ReturnResultProblem_vals), ""), 64); + g_strlcpy(problem_str, val_to_str_const(problem_val, VALS(h450_ros_ReturnResultProblem_vals), ""), 64); problem_str[64-1] = '\0'; return offset; @@ -489,7 +489,7 @@ dissect_h450_ros_ReturnErrorProblem(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_ offset = dissect_per_integer(tvb, offset, actx, tree, hf_index, &problem_val); #line 59 "../../asn1/h450-ros/h450-ros.cnf" - g_strlcpy(problem_str, val_to_str(problem_val, VALS(h450_ros_ReturnErrorProblem_vals), ""), 64); + g_strlcpy(problem_str, val_to_str_const(problem_val, VALS(h450_ros_ReturnErrorProblem_vals), ""), 64); problem_str[64-1] = '\0'; return offset; diff --git a/epan/dissectors/packet-lisp.c b/epan/dissectors/packet-lisp.c index 3c87d277d8..4f8781ae2b 100644 --- a/epan/dissectors/packet-lisp.c +++ b/epan/dissectors/packet-lisp.c @@ -1019,9 +1019,9 @@ dissect_lcaf_geo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offse offset += 1; proto_item_append_text(ti_lat, ": %s %d\302\260 %d' %d\"", - val_to_str(north, lat_typevals, ""), deg, min, sec); + val_to_str_const(north, lat_typevals, ""), deg, min, sec); proto_item_append_text(tir, ": (%s%d\302\260%d'%d\"", - val_to_str(north, lat_typevals, ""), deg, min, sec); + val_to_str_const(north, lat_typevals, ""), deg, min, sec); /* PROCESS LONGITUDE */ @@ -1056,9 +1056,9 @@ dissect_lcaf_geo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offse offset += 1; proto_item_append_text(ti_lon, ": %s %d\302\260 %d' %d\"", - val_to_str(east, lon_typevals, ""), deg, min, sec); + val_to_str_const(east, lon_typevals, ""), deg, min, sec); proto_item_append_text(tir, ", %s%d\302\260%d'%d\")", - val_to_str(east, lon_typevals, ""), deg, min, sec); + val_to_str_const(east, lon_typevals, ""), deg, min, sec); /* PROCESS ALTITUDE */ diff --git a/epan/dissectors/packet-ncp2222.inc b/epan/dissectors/packet-ncp2222.inc index 7fdc4fe714..352d9545c0 100644 --- a/epan/dissectors/packet-ncp2222.inc +++ b/epan/dissectors/packet-ncp2222.inc @@ -2855,6 +2855,7 @@ trap_for_expert_event(proto_tree *ncp_tree, packet_info *pinfo, const ncp_record } expert_add_info_format(pinfo, NULL, &ei_ncp_file_rights, + "Op-lock open, mode %s for filename %s with rights %s", val_to_str((guint32)(strtoul(oaction, NULL, 16) & 0xeb), open_create_mode_vals, "Unknown: %d"), p_filename, val_to_str((atoi(p_rights) & 0x5f), ncp_rights_vals, "Unknown: %d")); @@ -12062,3 +12063,16 @@ dissect_ping_req(tvbuff_t *tvb, packet_info *pinfo, CLEANUP_CALL_AND_POP; } } + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=4 expandtab filetype=c: + * :indentSize=4:tabSize=4:noTabs=true: + */ diff --git a/epan/dissectors/packet-q932-ros.c b/epan/dissectors/packet-q932-ros.c index 59a37a30eb..861278e5c2 100644 --- a/epan/dissectors/packet-q932-ros.c +++ b/epan/dissectors/packet-q932-ros.c @@ -507,7 +507,7 @@ dissect_q932_ros_GeneralProblem(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, in &problem_val); #line 53 "../../asn1/q932-ros/q932-ros.cnf" - g_strlcpy(problem_str, val_to_str(problem_val, VALS(q932_ros_GeneralProblem_vals), ""), 64); + g_strlcpy(problem_str, val_to_str_const(problem_val, VALS(q932_ros_GeneralProblem_vals), ""), 64); return offset; } @@ -532,7 +532,7 @@ dissect_q932_ros_InvokeProblem(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int &problem_val); #line 55 "../../asn1/q932-ros/q932-ros.cnf" - g_strlcpy(problem_str, val_to_str(problem_val, VALS(q932_ros_InvokeProblem_vals), ""), 64); + g_strlcpy(problem_str, val_to_str_const(problem_val, VALS(q932_ros_InvokeProblem_vals), ""), 64); return offset; } @@ -552,7 +552,7 @@ dissect_q932_ros_ReturnResultProblem(gboolean implicit_tag _U_, tvbuff_t *tvb _U &problem_val); #line 57 "../../asn1/q932-ros/q932-ros.cnf" - g_strlcpy(problem_str, val_to_str(problem_val, VALS(q932_ros_ReturnResultProblem_vals), ""), 64); + g_strlcpy(problem_str, val_to_str_const(problem_val, VALS(q932_ros_ReturnResultProblem_vals), ""), 64); return offset; } @@ -574,7 +574,7 @@ dissect_q932_ros_ReturnErrorProblem(gboolean implicit_tag _U_, tvbuff_t *tvb _U_ &problem_val); #line 59 "../../asn1/q932-ros/q932-ros.cnf" - g_strlcpy(problem_str, val_to_str(problem_val, VALS(q932_ros_ReturnErrorProblem_vals), ""), 64); + g_strlcpy(problem_str, val_to_str_const(problem_val, VALS(q932_ros_ReturnErrorProblem_vals), ""), 64); return offset; } diff --git a/epan/dissectors/packet-wreth.c b/epan/dissectors/packet-wreth.c index 5ab4bfe2a4..4bca480227 100644 --- a/epan/dissectors/packet-wreth.c +++ b/epan/dissectors/packet-wreth.c @@ -1182,7 +1182,7 @@ gint WrethMailDissection(tvbuff_t *tvb, guint8 Offset, packet_info * pInfo, prot col_add_fstr(pInfo->cinfo, COL_INFO, "Mail : Codef = Ox%X (%s), Status = %02d (%s), Card = %d, Chan = %d" , Codef, - val_to_str_ext(Codef, &tabCodef_ext, "Unknown 0x%04x%"), + val_to_str_ext(Codef, &tabCodef_ext, "Unknown 0x%04x"), Status, val_to_str_ext(Status, &tabStatus_ext, "Unknown %d"), Card, diff --git a/epan/dissectors/packet-x509if.c b/epan/dissectors/packet-x509if.c index fe6cae6de4..487794506c 100644 --- a/epan/dissectors/packet-x509if.c +++ b/epan/dissectors/packet-x509if.c @@ -744,7 +744,7 @@ dissect_x509if_T_type_02(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offse proto_item_append_text(tree, " (%s)", name); } - if((fmt = val_to_str(hf_index, fmt_vals, "")) && *fmt) { + if((fmt = val_to_str_const(hf_index, fmt_vals, "")) && *fmt) { /* we have a format */ last_ava = (char *)wmem_alloc(wmem_packet_scope(), MAX_AVA_STR_LEN); *last_ava = '\0'; register_frame_end_routine (actx->pinfo, x509if_frame_end); @@ -796,7 +796,7 @@ dissect_x509if_T_atadv_value(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int o proto_item_append_text(tree, "%s)", value); } - if((fmt = val_to_str(ava_hf_index, fmt_vals, "")) && *fmt) { + if((fmt = val_to_str_const(ava_hf_index, fmt_vals, "")) && *fmt) { /* we have a format */ if (!last_ava) { @@ -985,7 +985,7 @@ dissect_x509if_RDNSequence(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int off proto_item_append_text(top_of_dn, " (%s)", last_dn); /* see if we should append this to the col info */ - if((fmt = val_to_str(hf_index, fmt_vals, "")) && *fmt) { + if((fmt = val_to_str_const(hf_index, fmt_vals, "")) && *fmt) { /* we have a format */ col_append_fstr(actx->pinfo->cinfo, COL_INFO, " %s%s", fmt, last_dn); } diff --git a/epan/dissectors/packet-zbee-aps.c b/epan/dissectors/packet-zbee-aps.c index 0feeaa6b1b..8f7e053221 100644 --- a/epan/dissectors/packet-zbee-aps.c +++ b/epan/dissectors/packet-zbee-aps.c @@ -853,7 +853,7 @@ dissect_zbee_aps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data /* Display the profile ID now that the source endpoint was listed. */ if (packet.type == ZBEE_APS_FCF_DATA) { col_append_fstr(pinfo->cinfo, COL_PROTOCOL, " %s", - rval_to_str(packet.profile, zbee_aps_apid_abbrs, "")); + rval_to_str_const(packet.profile, zbee_aps_apid_abbrs, "")); } /* Jump here if there is no endpoint addressing in this frame. */ diff --git a/epan/emem.h b/epan/emem.h index 0ce3b20478..0e41294a61 100644 --- a/epan/emem.h +++ b/epan/emem.h @@ -75,10 +75,11 @@ void* ep_memdup(const void* src, size_t len) G_GNUC_MALLOC; /** Create a formatted string with a packet lifetime scope */ WS_DLL_PUBLIC -gchar* ep_strdup_vprintf(const gchar* fmt, va_list ap) G_GNUC_MALLOC; +gchar* ep_strdup_vprintf(const gchar* fmt, va_list ap) + G_GNUC_MALLOC G_GNUC_PRINTF(1, 0); WS_DLL_PUBLIC gchar* ep_strdup_printf(const gchar* fmt, ...) - G_GNUC_MALLOC G_GNUC_PRINTF(1, 2); + G_GNUC_MALLOC G_GNUC_PRINTF(1, 2); WS_DLL_PUBLIC gchar *ep_strconcat(const gchar *string, ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED; diff --git a/epan/except.h b/epan/except.h index 8db5acb7c5..063218274a 100644 --- a/epan/except.h +++ b/epan/except.h @@ -95,7 +95,8 @@ WS_DLL_PUBLIC void except_deinit(void); WS_DLL_PUBLIC WS_MSVC_NORETURN void except_rethrow(except_t *) G_GNUC_NORETURN; WS_DLL_PUBLIC WS_MSVC_NORETURN void except_throw(long, long, const char *) G_GNUC_NORETURN; WS_DLL_PUBLIC WS_MSVC_NORETURN void except_throwd(long, long, const char *, void *) G_GNUC_NORETURN; -WS_DLL_PUBLIC WS_MSVC_NORETURN void except_throwf(long, long, const char *, ...) G_GNUC_NORETURN; +WS_DLL_PUBLIC WS_MSVC_NORETURN void except_throwf(long, long, const char *, ...) + G_GNUC_NORETURN G_GNUC_PRINTF(3, 4); WS_DLL_PUBLIC void (*except_unhandled_catcher(void (*)(except_t *)))(except_t *); extern unsigned long except_code(except_t *); extern unsigned long except_group(except_t *); diff --git a/epan/proto.h b/epan/proto.h index c3a5ab38ea..8f6bc9f178 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -877,7 +877,8 @@ proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, co @return the newly created item */ proto_item * proto_tree_add_text_valist(proto_tree *tree, tvbuff_t *tvb, gint start, - gint length, const char *format, va_list ap); + gint length, const char *format, va_list ap) + G_GNUC_PRINTF(5, 0); /** Add a text-only node that creates a subtree underneath. proto_tree_add_text + proto_item_add_subtree diff --git a/epan/ptvcursor.h b/epan/ptvcursor.h index 55663f332d..ad85c312a3 100644 --- a/epan/ptvcursor.h +++ b/epan/ptvcursor.h @@ -111,7 +111,8 @@ ptvcursor_add_with_subtree(ptvcursor_t* ptvc, int hfindex, gint length, WS_DLL_PUBLIC proto_tree* ptvcursor_add_text_with_subtree(ptvcursor_t* ptvc, gint length, - gint ett_subtree, const char* format, ...); + gint ett_subtree, const char* format, ...) + G_GNUC_PRINTF(4, 5); /* Creates a subtree and adds it to the cursor as the working tree but does not * save the old working tree */ diff --git a/epan/to_str.h b/epan/to_str.h index 9b3880c342..6d180dba44 100644 --- a/epan/to_str.h +++ b/epan/to_str.h @@ -99,7 +99,7 @@ WS_DLL_PUBLIC char *other_decode_bitfield_value(char *buf, const guint32 val, co WS_DLL_PUBLIC char *decode_bitfield_value(char *buf, const guint32 val, const guint32 mask, const int width); WS_DLL_PUBLIC const char *decode_numeric_bitfield(const guint32 val, const guint32 mask, const int width, - const char *fmt); + const char *fmt) G_GNUC_PRINTF(4, 0); WS_DLL_PUBLIC const gchar* port_type_to_str (port_type type); diff --git a/epan/value_string.h b/epan/value_string.h index d62c2d7951..c7b57f9a89 100644 --- a/epan/value_string.h +++ b/epan/value_string.h @@ -113,7 +113,8 @@ enum { \ WS_DLL_PUBLIC const gchar * -val_to_str(const guint32 val, const value_string *vs, const char *fmt); +val_to_str(const guint32 val, const value_string *vs, const char *fmt) +G_GNUC_PRINTF(3, 0); WS_DLL_PUBLIC const gchar * @@ -136,7 +137,8 @@ typedef struct _val64_string { WS_DLL_PUBLIC const gchar * -val64_to_str(const guint64 val, const val64_string *vs, const char *fmt); +val64_to_str(const guint64 val, const val64_string *vs, const char *fmt) +G_GNUC_PRINTF(3, 0); WS_DLL_PUBLIC const gchar * @@ -193,7 +195,8 @@ value_string_ext_free(const value_string_ext *vse); WS_DLL_PUBLIC const gchar * -val_to_str_ext(const guint32 val, const value_string_ext *vs, const char *fmt); +val_to_str_ext(const guint32 val, const value_string_ext *vs, const char *fmt) +G_GNUC_PRINTF(3, 0); WS_DLL_PUBLIC const gchar * @@ -216,7 +219,8 @@ typedef struct _string_string { WS_DLL_PUBLIC const gchar * -str_to_str(const gchar *val, const string_string *vs, const char *fmt); +str_to_str(const gchar *val, const string_string *vs, const char *fmt) +G_GNUC_PRINTF(3, 0); WS_DLL_PUBLIC const gchar * @@ -236,7 +240,8 @@ typedef struct _range_string { WS_DLL_PUBLIC const gchar * -rval_to_str(const guint32 val, const range_string *rs, const char *fmt); +rval_to_str(const guint32 val, const range_string *rs, const char *fmt) +G_GNUC_PRINTF(3, 0); WS_DLL_PUBLIC const gchar * |