about summary refs log tree commit
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-06-02 21:39:14 +0000
committerEric Wong <normalperson@yhbt.net>2011-06-02 21:40:01 +0000
commit9683fd2d552a0c22442186f1ea9974c478eefb2a (patch)
treebf02a0af708fb86f17ff83a9acb4a05f5813666f
parentd5c6ce5b1c2f67920bb9499d7f79ed0a5a75ced2 (diff)
downloadrpatricia-9683fd2d552a0c22442186f1ea9974c478eefb2a.tar.gz
fix assertions from IPv6 <-> IPv4 mismatches
Hitting assertions in C code is bad user-experience, raise in
Ruby-land before this happens.
-rw-r--r--ext/rpatricia/rpatricia.c20
-rw-r--r--test/test_old_segfaults.rb10
2 files changed, 24 insertions, 6 deletions
diff --git a/ext/rpatricia/rpatricia.c b/ext/rpatricia/rpatricia.c
index f8ce0b5..4132c32 100644
--- a/ext/rpatricia/rpatricia.c
+++ b/ext/rpatricia/rpatricia.c
@@ -44,7 +44,7 @@ wrap_node(patricia_node_t *orig)
 }
 
 static prefix_t *
-my_ascii2prefix(VALUE str)
+my_ascii2prefix(patricia_tree_t *tree, VALUE str)
 {
   char *cstr = StringValuePtr(str);
   prefix_t *prefix = ascii2prefix(cstr);
@@ -52,6 +52,14 @@ my_ascii2prefix(VALUE str)
   if (!prefix)
     rb_raise(rb_eArgError, "invalid prefix: %s", cstr);
 
+  if (prefix->bitlen > tree->maxbits) {
+    unsigned bitlen = prefix->bitlen;
+
+    Deref_Prefix(prefix);
+    rb_raise(rb_eArgError, "prefix length (%u) larger than maxbits (%u)",
+             bitlen, tree->maxbits);
+  }
+
   return prefix;
 }
 
@@ -67,7 +75,7 @@ p_add (int argc, VALUE *argv, VALUE self)
     return Qnil;
 
   Data_Get_Struct(self, patricia_tree_t, tree);
-  prefix = my_ascii2prefix(argv[0]);
+  prefix = my_ascii2prefix(tree, argv[0]);
   node = patricia_lookup(tree, prefix);
   Deref_Prefix(prefix);
 
@@ -94,7 +102,7 @@ p_remove (VALUE self, VALUE r_key)
   prefix_t *prefix;
 
   Data_Get_Struct(self, patricia_tree_t, tree);
-  prefix = my_ascii2prefix(r_key);
+  prefix = my_ascii2prefix(tree, r_key);
   node = patricia_search_exact(tree, prefix);
   Deref_Prefix (prefix);
 
@@ -114,7 +122,7 @@ p_match (VALUE self, VALUE r_key)
   prefix_t *prefix;
   
   Data_Get_Struct(self, patricia_tree_t, tree);
-  prefix = my_ascii2prefix(r_key);
+  prefix = my_ascii2prefix(tree, r_key);
   node = patricia_search_best(tree, prefix);
   Deref_Prefix (prefix);
 
@@ -129,7 +137,7 @@ p_include (VALUE self, VALUE r_key)
   prefix_t *prefix;
 
   Data_Get_Struct(self, patricia_tree_t, tree);
-  prefix = my_ascii2prefix(r_key);
+  prefix = my_ascii2prefix(tree, r_key);
   node = patricia_search_best(tree, prefix);
   Deref_Prefix (prefix);
 
@@ -144,7 +152,7 @@ p_match_exact (VALUE self, VALUE r_key)
   prefix_t *prefix;
 
   Data_Get_Struct(self, patricia_tree_t, tree);
-  prefix = my_ascii2prefix(r_key);
+  prefix = my_ascii2prefix(tree, r_key);
   node = patricia_search_exact(tree, prefix);
   Deref_Prefix (prefix);
 
diff --git a/test/test_old_segfaults.rb b/test/test_old_segfaults.rb
index 96f1b43..5366478 100644
--- a/test/test_old_segfaults.rb
+++ b/test/test_old_segfaults.rb
@@ -31,6 +31,16 @@ class TestOldSegfaults < Test::Unit::TestCase
     assert_equal 0, t.num_nodes
   end
 
+  def test_v6_v4_mismatch_search_best
+    t = Patricia.new
+    assert_raises(ArgumentError) { t.search_exact("::1/128") }
+  end
+
+  def test_v6_v4_mismatch_search_exact
+    t = Patricia.new
+    assert_raises(ArgumentError) { t.search_exact("::1/128") }
+  end
+
   def test_gc_ordering_segfault
     added = []
     100000.times do