Faulty assumption seems to be that counting references only to RVALUEs (Ruby objects in heap) is enough to determine if a part of memory can be freed. This breaks down in C-extensions where macros extract some part of the object or something pointed by it for use. In this case RSTRING_PTR extracts the C char-array used by str for zstream_append_input to use (lets call it arr).
If zstream_append_input or any calls underneath it tries to allocate a new Ruby object, GC may get called and str (and thus arr) may get freed because there are no references left to it anymore (no heap/stack/register because the register value was overwritten).
And this seems to require all Ruby C-extension writers to lock the objects they're using through macros with RB_GC_GUARD.
Edit: note that there are no references left to str
Perhaps the GC could be modified to track pointers not just to the head of object but to any address within it. Alternatively, C-coders working with Ruby could just say "I'm using this gc object" before calling C code.
I don't see this is a fatal flaw at all. Sounds like its just a bug. Now if, as many here assert, this bug is present all over the Ruby VM, then that's pretty unfortunate. Is that the case, or just hyperbole?