Question

I've written a simple Ruby C extension. A method expects the second parameter to be a string-ish VALUE.

VALUE method_foo(VALUE self, VALUE key) {

  puts(RSTRING(key)->ptr);

  return key;
}

Its very easy to cause a segmentation fault by passing an integer rather than a string. How should I detect this and either prevent or recover in the C method?

Was it helpful?

Solution

You should look into calling Check_Type (key, T_STRING) (if you want an exception raised) or using TYPE (key) to check it manually (if you want to do something other than raise an exception).

Alternatively, you could simply state that method_foo expects a string and leave it up to the caller to handle. Your API is, after all, a contract between caller and callee and, if the caller breaks the rules, it's a perfectly valid response to crash.

I probably wouldn't do that since I prefer robust software but there's a school of thought that people shouldn't always necessarily be protected from their own foolishness. It only encourages them to stay foolish :-)

OTHER TIPS

StringValuePtr(value) and StringValueCStr(value) do the typechecking and return the string pointers. AFAIK, they are the accepted ways to extract a char* from a Ruby string in a C extension. Among things (as far as I remember when I looked into it), they both make sure that the returned value is not NULL (which can be in some cases), and StringValueCStr also makes sure that it is a 0-terminated string. Since Ruby strings use copy-on-write, a slice of a string might not be 0-terminated.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top