Permalink
Browse files

prevent stack overflow for massive binaries in c decoder

  • Loading branch information...
1 parent 9257ecc commit b3dee26c8738a2ed821d8097c54f8fcda0c50cf5 @mojombo committed Oct 28, 2009
Showing with 13 additions and 7 deletions.
  1. +1 −0 History.txt
  2. +7 −7 ext/decoder.c
  3. +5 −0 test/decode_spec.rb
View
@@ -1,6 +1,7 @@
==
* Bug Fixes
* Fix bignum encoding
+ * Prevent stack overflow for massive binaries in c decoder
== 1.1.0 / 2009-10-08
* Minor Improvements
View
@@ -97,7 +97,7 @@ VALUE read_large_tuple(unsigned char **pData) {
rb_raise(rb_eStandardError, "Invalid Type, not a large tuple");
}
- int arity = read_4(pData);
+ unsigned int arity = read_4(pData);
VALUE array = rb_ary_new2(arity);
@@ -114,7 +114,7 @@ VALUE read_list(unsigned char **pData) {
rb_raise(rb_eStandardError, "Invalid Type, not an erlang list");
}
- int size = read_4(pData);
+ unsigned int size = read_4(pData);
VALUE newref_class = rb_const_get(mErlectricity, rb_intern("List"));
VALUE array = rb_funcall(newref_class, rb_intern("new"), 1, INT2NUM(size));
@@ -131,7 +131,7 @@ VALUE read_list(unsigned char **pData) {
// primitives
-void read_string_raw(unsigned char *dest, unsigned char **pData, int length) {
+void read_string_raw(unsigned char *dest, unsigned char **pData, unsigned int length) {
memcpy((char *) dest, (char *) *pData, length);
*(dest + length) = (unsigned char) 0;
*pData += length;
@@ -142,12 +142,12 @@ VALUE read_bin(unsigned char **pData) {
rb_raise(rb_eStandardError, "Invalid Type, not an erlang binary");
}
- int length = read_4(pData);
+ unsigned int length = read_4(pData);
- unsigned char buf[length + 1];
- read_string_raw(buf, pData, length);
+ VALUE rStr = rb_str_new((char *) *pData, length);
+ *pData += length;
- return rb_str_new((char *) buf, length);
+ return rStr;
}
VALUE read_string(unsigned char **pData) {
View
@@ -127,6 +127,11 @@
get("f").should == :f
end
+ specify "massive binaries should not overflow the stack" do
+ bin = [131,109,0,128,0,0].pack('c*') + ('a' * (8 * 1024 * 1024))
+ assert_equal (8 * 1024 * 1024), Erlectricity::Decoder.decode(bin).size
+ end
+
specify "a good thing should be awesome" do
get(%Q-[{options,{struct,[{test,<<"I'm chargin' mah lazer">>}]}},{passage,<<"Why doesn't this work?">>}]-).should ==
[[:options, [:struct, [[:test, "I'm chargin' mah lazer"]]]], [:passage, "Why doesn't this work?"]]

0 comments on commit b3dee26

Please sign in to comment.