about summary refs log tree commit
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-09-01 15:08:51 -0700
committerEric Wong <normalperson@yhbt.net>2010-09-01 16:44:43 -0700
commitd993ccd8f8846baa5434ab72bc8c159343baae79 (patch)
treed6f3d22a5ab22cab2e840ef9bf76b4b98cc2d8e7
parent976fd73a773dcda341c5b64e4d194ca257f47393 (diff)
downloadrpatricia-d993ccd8f8846baa5434ab72bc8c159343baae79.tar.gz
raise ArgumentError with invalid addresses
This is preferable to hitting an assertion and killing
the running process.  The plan is this code will deal with
potentially hostile/invalid user inputs in a network server,
so we do not have the luxury if just letting a process die.
-rw-r--r--ext/rpatricia/rpatricia.c22
-rw-r--r--test/test_invalid_inputs.rb27
2 files changed, 43 insertions, 6 deletions
diff --git a/ext/rpatricia/rpatricia.c b/ext/rpatricia/rpatricia.c
index 828aebd..a71ddac 100644
--- a/ext/rpatricia/rpatricia.c
+++ b/ext/rpatricia/rpatricia.c
@@ -30,6 +30,18 @@ p_node_mark (void *ptr)
   rb_gc_mark((VALUE)node->data);
 }
 
+static prefix_t *
+my_ascii2prefix(int family, VALUE str)
+{
+  char *cstr = StringValuePtr(str);
+  prefix_t *prefix = ascii2prefix(family, cstr);
+
+  if (!prefix)
+    rb_raise(rb_eArgError, "invalid prefix: %s", cstr);
+
+  return prefix;
+}
+
 static VALUE
 p_add (int argc, VALUE *argv, VALUE self)
 {
@@ -42,7 +54,7 @@ p_add (int argc, VALUE *argv, VALUE self)
     return Qnil;
 
   Data_Get_Struct(self, patricia_tree_t, tree);
-  prefix = ascii2prefix(AF_INET, StringValuePtr(argv[0]));
+  prefix = my_ascii2prefix(AF_INET, argv[0]);
   node = patricia_lookup(tree, prefix);
   Deref_Prefix(prefix);
 
@@ -64,14 +76,12 @@ p_add (int argc, VALUE *argv, VALUE self)
 static VALUE
 p_remove (VALUE self, VALUE r_key)
 {
-  char *c_key;
   patricia_tree_t *tree;
   patricia_node_t *node;
   prefix_t *prefix;
 
   Data_Get_Struct(self, patricia_tree_t, tree);
-  c_key = StringValuePtr(r_key);
-  prefix = ascii2prefix (AF_INET, c_key);
+  prefix = my_ascii2prefix (AF_INET, r_key);
   node = patricia_search_exact(tree, prefix);
   Deref_Prefix (prefix);
 
@@ -91,7 +101,7 @@ p_match (VALUE self, VALUE r_key)
   prefix_t *prefix;
   
   Data_Get_Struct(self, patricia_tree_t, tree);
-  prefix = ascii2prefix (AF_INET, StringValuePtr(r_key));
+  prefix = my_ascii2prefix (AF_INET, r_key);
   node = patricia_search_best(tree, prefix);
   Deref_Prefix (prefix);
 
@@ -110,7 +120,7 @@ p_match_exact (VALUE self, VALUE r_key)
   prefix_t *prefix;
 
   Data_Get_Struct(self, patricia_tree_t, tree);
-  prefix = ascii2prefix (AF_INET, StringValuePtr(r_key));
+  prefix = my_ascii2prefix (AF_INET, r_key);
   node = patricia_search_exact(tree, prefix);
   Deref_Prefix (prefix);
 
diff --git a/test/test_invalid_inputs.rb b/test/test_invalid_inputs.rb
new file mode 100644
index 0000000..93e7a96
--- /dev/null
+++ b/test/test_invalid_inputs.rb
@@ -0,0 +1,27 @@
+require 'test/unit'
+require 'rpatricia'
+
+class TestInvalidInput < Test::Unit::TestCase
+
+  def setup
+    @t = Patricia.new
+  end
+
+  def test_invalid_add
+    assert_raises(ArgumentError) { @t.add('1000.0.0.0/8') }
+    assert_raises(ArgumentError) { @t.add("\0") }
+    assert_raises(ArgumentError) { @t.add("\0\0\0\0\0\0" * 1024 * 1024) }
+  end
+
+  def test_invalid_remove
+    assert_raises(ArgumentError) { @t.remove('1000.0.0.0/8') }
+  end
+
+  def test_invalid_match_best
+    assert_raises(ArgumentError) { @t.match_best('1000.0.0.0/8') }
+  end
+
+  def test_invalid_match_exact
+    assert_raises(ArgumentError) { @t.match_exact('1000.0.0.0/8') }
+  end
+end