]> git.ipfire.org Git - thirdparty/mtr.git/commitdiff
crash fix: ctl->iiwidth_len was not initialized correctly
authorSami Kerola <kerolasa@iki.fi>
Sun, 4 Sep 2016 00:12:08 +0000 (01:12 +0100)
committerSami Kerola <kerolasa@iki.fi>
Sun, 4 Sep 2016 20:12:48 +0000 (21:12 +0100)
It was a mistake to add iiwidth_len to struct mtr_ctl.  First of all the
value needed in that field was never set, and that resulted to crash when
running command with --csv option.

Secondly adding the field was bad idea to begin with.  Number of array
elements is known only within context of asn.c file, so it is better to add
interface to query it rather than try to set value to a structure.  Later
design is prone to cause futher bugs, if/when execution flow is not as one
might assume.

asn.c
asn.h
mtr.h
report.c

diff --git a/asn.c b/asn.c
index a19671fa95fa86a6ff27d62660281220bacc7f61..4202f669fad2bbd4024855685ffb659897044af3 100644 (file)
--- a/asn.c
+++ b/asn.c
@@ -252,10 +252,16 @@ static char *get_ipinfo(struct mtr_ctl *ctl, ip_t *addr){
     return val;
 }
 
-extern int get_iiwidth (struct mtr_ctl *ctl) {
-  return (ctl->ipinfo_no <
-         ctl->iiwidth_len) ? iiwidth[ctl->ipinfo_no] :
-                             iiwidth[ctl->ipinfo_no % ctl->iiwidth_len];
+extern ATTRIBUTE_CONST size_t get_iiwidth_len(void) {
+    return (sizeof(iiwidth) / sizeof((iiwidth)[0]));
+}
+
+extern int get_iiwidth(struct mtr_ctl *ctl) {
+    static const int len = (sizeof(iiwidth) / sizeof((iiwidth)[0]));
+
+    if (ctl->ipinfo_no < len)
+        return iiwidth[ctl->ipinfo_no];
+    return iiwidth[ctl->ipinfo_no % len];
 }
 
 extern char *fmt_ipinfo(struct mtr_ctl *ctl, ip_t *addr){
diff --git a/asn.h b/asn.h
index 76fd0e4a747acc9e9684beb520119090a8fef851..adea4896ee2a57417a7ba1984fad4157c02d99ca 100644 (file)
--- a/asn.h
+++ b/asn.h
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include "mtr.h"
+
 extern void asn_open(struct mtr_ctl *ctl);
 extern void asn_close(struct mtr_ctl *ctl);
 extern char *fmt_ipinfo(struct mtr_ctl *ctl, ip_t *addr);
+extern ATTRIBUTE_CONST size_t get_iiwidth_len(void);
 extern int get_iiwidth(struct mtr_ctl *ctl);
 extern int is_printii(struct mtr_ctl *ctl);
diff --git a/mtr.h b/mtr.h
index 2bd9ab7ec1707d30086bd8e6d759a0f0640c2792..494d0eda67081fc34077cb2c6f5d6eec0a86f5f8 100644 (file)
--- a/mtr.h
+++ b/mtr.h
@@ -37,6 +37,13 @@ typedef struct in_addr ip_t;
 #define UNUSED
 #endif
 
+/* The __const__ attribute was added in gcc 2.95.  */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
+# define ATTRIBUTE_CONST __attribute__ ((__const__))
+#else
+# define ATTRIBUTE_CONST /* empty */
+#endif
+
 /* stuff used by display such as report, curses... */
 #define MAXFLD 20              /* max stats fields to display */
 #define FLD_INDEX_SZ 256
@@ -54,7 +61,6 @@ struct mtr_ctl {
   char LocalHostname[128];
   int ipinfo_no;
   int ipinfo_max;
-  int iiwidth_len;
   int cpacketsize;             /* packet size used by ping */
   int bitpattern;              /* packet bit pattern used by ping */
   int tos;                     /* type of service set in ping packet*/
index 9f9082f979df5447c0ded21d30ad62babad8e0d9..93568fb1ac86359e72b616e6530cdd2ff95027ae 100644 (file)
--- a/report.c
+++ b/report.c
@@ -95,8 +95,9 @@ extern void report_close(struct mtr_ctl *ctl)
   
 #ifdef HAVE_IPINFO
   int len_tmp = len_hosts;
-  if (ctl->ipinfo_no >= 0 && ctl->iiwidth_len) {
-    ctl->ipinfo_no %= ctl->iiwidth_len;
+  const size_t iiwidth_len = get_iiwidth_len();
+  if (ctl->ipinfo_no >= 0 && iiwidth_len) {
+    ctl->ipinfo_no %= iiwidth_len;
     if (ctl->reportwide) {
       len_hosts++;    // space
       len_tmp   += get_iiwidth(ctl);