From 77f0be59a45d9ed6dd5f87c8cff90da90a17e421 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 2 Jun 2011 20:21:34 +0000 Subject: prefix_toa2x requires proper length for IPv6 We have the INET6_ADDRSTRLEN constant to help us determine the proper length. --- ext/rpatricia/patricia.c | 45 +++++++++++++++++++-------------------------- ext/rpatricia/patricia.h | 1 + ext/rpatricia/rpatricia.c | 24 ++++++++++++++++-------- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/ext/rpatricia/patricia.c b/ext/rpatricia/patricia.c index fcbb110..44cc01c 100644 --- a/ext/rpatricia/patricia.c +++ b/ext/rpatricia/patricia.c @@ -70,39 +70,32 @@ comp_with_mask (void *addr, void *dest, u_int mask) /* * convert prefix information to ascii string with length * thread safe and re-entrant implementation + * + * buff must be at least PATRICIA_MAXSTRLEN bytes large if with_len is true + * buff must be at least INET6_ADDRSTRLEN bytes large if with_len is false */ char * prefix_toa2x (prefix_t *prefix, char *buff, int with_len) { - if (prefix == NULL) - return ("(Null)"); - assert (prefix->ref_count >= 0); + assert(prefix && "NULL prefix not allowed"); + assert(prefix->ref_count >= 0); assert(buff != NULL && "buffer must be specified"); - if (prefix->family == AF_INET) { - u_char *a; - assert (prefix->bitlen <= 32); - a = prefix_touchar (prefix); - if (with_len) { - sprintf (buff, "%d.%d.%d.%d/%d", a[0], a[1], a[2], a[3], - prefix->bitlen); - } - else { - sprintf (buff, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]); - } - return (buff); - } - else if (prefix->family == AF_INET6) { - char *r; - r = (char *) inet_ntop (AF_INET6, &prefix->add.sin6, buff, 48 /* a guess value */ ); - if (r && with_len) { - assert (prefix->bitlen <= 128); - sprintf (buff + strlen (buff), "/%d", prefix->bitlen); - } - return (buff); + switch (prefix->family) { + case AF_INET: + assert(prefix->bitlen <= 32 && "bitlen > 32 for AF_INET"); + break; + case AF_INET6: + assert(prefix->bitlen <= 128 && "bitlen > 128 for AF_INET6"); + break; + default: + assert(0 && "unknown address family (memory corruption?)"); } - else - return (NULL); + buff = inet_ntop(prefix->family, &prefix->add.sin6, buff, INET6_ADDRSTRLEN); + assert(buff && "corrupt address"); + if (with_len) + sprintf(buff + strlen(buff), "/%u", prefix->bitlen); + return (buff); } /* prefix_toa2 diff --git a/ext/rpatricia/patricia.h b/ext/rpatricia/patricia.h index d4bb7ab..f4abffd 100644 --- a/ext/rpatricia/patricia.h +++ b/ext/rpatricia/patricia.h @@ -91,6 +91,7 @@ ascii2prefix (char *string); /* } */ #define PATRICIA_MAXBITS 128 +#define PATRICIA_MAXSTRLEN (INET6_ADDRSTRLEN + sizeof("/128") - 1) #define PATRICIA_NBIT(x) (0x80 >> ((x) & 0x7f)) #define PATRICIA_NBYTE(x) ((x) >> 3) diff --git a/ext/rpatricia/rpatricia.c b/ext/rpatricia/rpatricia.c index 98b9b35..17534c6 100644 --- a/ext/rpatricia/rpatricia.c +++ b/ext/rpatricia/rpatricia.c @@ -177,7 +177,7 @@ p_print_nodes (int argc, VALUE *argv, VALUE self) { ID id_printf = rb_intern("printf"); VALUE fmt = rb_str_new2("node: %s\n"); - VALUE buf = rb_str_buf_new(128); + VALUE buf = rb_str_new(0, 0); char *cbuf; patricia_tree_t *tree; patricia_node_t *node; @@ -190,7 +190,7 @@ p_print_nodes (int argc, VALUE *argv, VALUE self) if (tree->head) { PATRICIA_WALK(tree->head, node) { - rb_str_resize(buf, 128); + rb_str_resize(buf, PATRICIA_MAXSTRLEN); cbuf = RSTRING_PTR(buf); prefix_toa2x(node->prefix, cbuf, 1); rb_str_set_len(buf, strlen(cbuf)); @@ -219,21 +219,29 @@ p_data (VALUE self) static VALUE p_network (VALUE self) { - char buff[32]; patricia_node_t *node; + VALUE str = rb_str_new(0, PATRICIA_MAXSTRLEN); + char *cstr = RSTRING_PTR(str); + Data_Get_Struct(self, patricia_node_t, node); - prefix_toa2x (node->prefix, buff, 0); - return rb_str_new2(buff); + prefix_toa2x(node->prefix, cstr, 0); + rb_str_set_len(str, strlen(cstr)); + + return str; } static VALUE p_prefix (VALUE self) { - char buff[32]; patricia_node_t *node; + VALUE str = rb_str_new(0, INET6_ADDRSTRLEN); + char *cstr = RSTRING_PTR(str); + Data_Get_Struct(self, patricia_node_t, node); - prefix_toa2 (node->prefix, buff); - return rb_str_new2(buff); + prefix_toa2(node->prefix, cstr); + rb_str_set_len(str, strlen(cstr)); + + return str; } static VALUE -- cgit v1.2.3-24-ge0c7