summary refs log tree commit
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-08-09 03:48:59 +0000
committerEric Wong <normalperson@yhbt.net>2011-08-09 03:51:43 +0000
commit40869aa9fc8ab194813b850071a43a5a52aff7d8 (patch)
tree5c0b4f873cea5dbc28bc31c1335aab823c5e5016
parent8a82bffe927e8928e304b9610a75ea07b0c4a798 (diff)
downloadruby-json-40869aa9fc8ab194813b8.tar.gz
json/generator: enforce Strings for fbuffer_append_str HEAD master
"to_s" is not guaranteed to return a string and calling
RSTRING_ macros on them blindly can cause bus errors/segfaults.

Found by nobu: [ruby-core:38867]
-rw-r--r--ext/json/ext/generator/generator.c2
-rwxr-xr-xtests/test_json_generate.rb21
2 files changed, 22 insertions, 1 deletions
diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c
index a75118a..b410eb7 100644
--- a/ext/json/ext/generator/generator.c
+++ b/ext/json/ext/generator/generator.c
@@ -351,7 +351,7 @@ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
 
 static void fbuffer_append_str(FBuffer *fb, VALUE str)
 {
-    const char *newstr = RSTRING_PTR(str);
+    const char *newstr = StringValuePtr(str);
     unsigned long len = RSTRING_LEN(str);
 
     RB_GC_GUARD(str);
diff --git a/tests/test_json_generate.rb b/tests/test_json_generate.rb
index bc4e395..368a27e 100755
--- a/tests/test_json_generate.rb
+++ b/tests/test_json_generate.rb
@@ -190,4 +190,25 @@ EOT
     ensure
       GC.stress = stress
   end if GC.respond_to?(:stress=)
+
+
+  def test_broken_bignum # [ruby-core:38867]
+    pid = fork do
+      Bignum.class_eval do
+        def to_s
+        end
+      end
+      begin
+        JSON::Ext::Generator::State.new.generate(1<<64)
+        exit 1
+      rescue TypeError
+        exit 0
+      end
+    end
+    _, status = Process.waitpid2(pid)
+    assert status.success?
+    rescue NotImplementedError
+      # forking to avoid modifying core class of a parent process and
+      # introducing race conditions of tests are run in parallel
+  end
 end