diff options
author | Eric Wong <normalperson@yhbt.net> | 2010-09-01 15:08:51 -0700 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2010-09-01 16:44:43 -0700 |
commit | d993ccd8f8846baa5434ab72bc8c159343baae79 (patch) | |
tree | d6f3d22a5ab22cab2e840ef9bf76b4b98cc2d8e7 | |
parent | 976fd73a773dcda341c5b64e4d194ca257f47393 (diff) | |
download | rpatricia-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.c | 22 | ||||
-rw-r--r-- | test/test_invalid_inputs.rb | 27 |
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 |