Hi, I filed a bug report in the tracker (id #15169) a short while ago, along with a patch, but I came back to it to see that there is relatively little movement or participation on the tracker so I thought I'd pitch it here (patch attached).
The function `set_rl_word_breaks` in src/unix/sys-std.c relies on statically-allocated strings local to the function, making other C code using the readline library, such as a program embedding R and using readline as well, at risk of creating a segfault when trying to free `rl_basic_word_break_characters` or `rl_completer_word_break_characters` when changing them. The issue was noticed when embedding R in Python (rpy2); I had an ugly hack for a long time (less work than champion the inclusion of a patch in R) but the iPython developers pushed what could be demanded from the rpy2 with their "R magic" extension and so I wrote a patch (and they have made a brittle workaround in the meantime). The fix would be of interest to anyone embedding R in C and using readline (e.g., language interface developers if the language either has a console using readline - and chances are that it does - or an interface to readline). The patch attached is against today's R-dev and will likely apply to current R-2.15 branch. With the patch applied, R is building and is passing `make check`. It could be slightly expanded by handling cases where the calloc() or realloc() faills, although not an absolute priority (if allocating 200 bytes fails, the system might have bigger worries than keeping R from crashing). Laurent
Index: src/unix/sys-std.c =================================================================== --- src/unix/sys-std.c (revision 61791) +++ src/unix/sys-std.c (working copy) @@ -619,12 +619,31 @@ attribute_hidden void set_rl_word_breaks(const char *str) { - static char p1[201], p2[203]; - strncpy(p1, str, 200); p1[200]= '\0'; - strncpy(p2, p1, 200); p2[200] = '\0'; - strcat(p2, "[]"); - rl_basic_word_break_characters = p2; - rl_completer_word_break_characters = p1; + static char *completer_word_break_characters = NULL; + static char *basic_word_break_characters = NULL; + + if (completer_word_break_characters == NULL) { + completer_word_break_characters = calloc(201, sizeof(char)); + } else { + completer_word_break_characters = realloc(completer_word_break_characters, + 201 * sizeof(char)); + } + strncpy(completer_word_break_characters, str, 200); + completer_word_break_characters[200]= '\0'; + + if (basic_word_break_characters == NULL) { + basic_word_break_characters = calloc(203, sizeof(char)); + } else { + basic_word_break_characters = realloc(basic_word_break_characters, + 203 * sizeof(char)); + } + strncpy(basic_word_break_characters, + completer_word_break_characters, 200); + basic_word_break_characters[200] = '\0'; + strcat(basic_word_break_characters, "[]"); + + rl_completer_word_break_characters = completer_word_break_characters; + rl_basic_word_break_characters = basic_word_break_characters; }
______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel