Search code examples
cregexrubycrashc-api

Crash when trying to call ruby regex from c code


This post is a continuation of my previous post: (Call to ruby regex through C api from C code not working)

I did a few modifications and now I am calling the rb_reg_regcomp with "*".

#include <ruby.h>
#include "ruby/re.h"


#define MAX_INPUT_SIZE 1000

int main(int argc, char** argv) {
    VALUE x;
    char string[MAX_INPUT_SIZE];
    int result;
    result = ruby_setup();
    ruby_init();

    ruby_init_loadpath();




    memset(string, 0, MAX_INPUT_SIZE);

    fgets(string, MAX_INPUT_SIZE, stdin);

    if (string[MAX_INPUT_SIZE-2]) {
        return 0;
    }

    //printf("thing");
    x = rb_str_new_cstr("*");
    rb_reg_regcomp(x);




    


    return 0;

}

Now when I run this program and then press enter, I get this in gdb:

Program received signal SIGSEGV, Segmentation fault.
0x000055555565bef6 in rb_ec_tag_jump (st=st@entry=RUBY_TAG_RAISE, ec=<optimized out>) at ../eval_intern.h:161
161     ec->tag->state = st;
(gdb) where
#0  0x000055555565bef6 in rb_ec_tag_jump (st=st@entry=RUBY_TAG_RAISE, ec=<optimized out>) at ../eval_intern.h:161
#1  0x0000555555661fe0 in rb_longjmp (ec=ec@entry=0x6160000000d0, tag=tag@entry=6, mesg=<optimized out>, mesg@entry=140737288676920, cause=<optimized out>, cause@entry=36) at ../eval.c:658
#2  0x000055555566231d in rb_exc_exception (mesg=mesg@entry=140737288676920, tag=tag@entry=6, cause=cause@entry=36) at ../vm_core.h:1866
#3  0x0000555555668628 in rb_exc_raise (mesg=mesg@entry=140737288676920) at ../eval.c:684
#4  0x00005555559387a5 in rb_reg_raise_str (err=<optimized out>, options=0, str=140737288677040) at ../re.c:3300
#5  rb_reg_init_str (options=0, s=140737288677040, re=140737288677000) at ../re.c:3300
#6  rb_reg_new_str (options=0, s=140737288677040) at ../re.c:3291
#7  rb_reg_regcomp (str=140737288677040) at ../re.c:3373
#8  0x000055555565aca1 in main () at ../eval.c:856

How do I call the ruby regex function appropriately from c code such that the crash does not happen? Thanks in advance!

Edit: I compiled the ruby library from source. I am using commit a8e7fee80129b0ba360c2671582117c8e18a6464 .

Edit2: I know that "*" is not valid regex, but the original purpose of the program was to get a user to type their own regex and then make the ruby code compile the regex. This piece of code is to be used in a fuzzer which fuzzes the ruby regex parser to find bugs in it, so the program should be able to handle invalid regex strings gracefully instead of crashing.

Edit3: removed newline from the call to rb_str_new_cstr . Still crashes.


Solution

  • Yeah after reading the documentation I fixed the code. This code (I think) works perfectly:

    #include <ruby.h>
    #include "ruby/re.h"
    
    
    #define MAX_INPUT_SIZE 120
    
    
    
    
    VALUE handle_error(VALUE obj1) {
    
        return 0;
    }
    
    
    VALUE dangerous_func(VALUE x)
    {
        /* code that could raise an exception */
        int thing;
    
        thing = rb_reg_regcomp(x);
        printf("Regex return value: %d\n", thing);
        return thing;
    }
    
    int main(int argc, char** argv) {
        VALUE x;
    
        VALUE result;
    
        int state = 0;
        char string[MAX_INPUT_SIZE];
        ruby_setup();
        ruby_init();
    
        ruby_init_loadpath();
    
    
    
    
        state = 0;
    
        memset(string, 0, MAX_INPUT_SIZE);
    
        fgets(string, MAX_INPUT_SIZE, stdin);
    
        if (string[MAX_INPUT_SIZE-2]) {
            return 0;
        }
    
        x = rb_str_new_cstr(string);
    
        
        result = rb_protect(dangerous_func, x, &state);
    
        printf("result %d\n", state);
    
    
        return 0;
    
    }
    

    Thanks to @pmacfarlane for the info!