From 8420c5ad35e167c5e614dd70bf3922722fa809e0 Mon Sep 17 00:00:00 2001 From: Jakub Zakrzewski Date: Sat, 23 Sep 2017 23:49:17 +0200 Subject: [PATCH 1/2] Saner behavior in rb_gsl_complex_printf. Use Ruby string formatting instead of sprintf in rb_gsl_complex_printf. This changes the behavior in some ways: * the function will no longer print/leak garbage from the stack if it is given a format string with too many directives. It will raise an ArgumentError instead. * the function can no longer crash ruby by overflowing the stack with a long format string * the availability and behavior of directives will match ruby sprintf and not given system's libc * saner type conversion rules will be used (e.g. "%d" will actually print out the integer parts of the complex number instead of reinterpreting the bits of the float as an integer) --- ext/gsl_native/complex.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ext/gsl_native/complex.c b/ext/gsl_native/complex.c index a637787d..c3c5f1b9 100644 --- a/ext/gsl_native/complex.c +++ b/ext/gsl_native/complex.c @@ -166,12 +166,16 @@ static VALUE rb_gsl_complex_print(VALUE obj) static VALUE rb_gsl_complex_printf(VALUE obj, VALUE s) { gsl_complex *c = NULL; - char tmp[32], format[64]; + VALUE format, out; + VALUE vals[2]; Check_Type(s, T_STRING); Data_Get_Struct(obj, gsl_complex, c); - strcpy(tmp, STR2CSTR(s)); - sprintf(format, "%s %s\n", tmp, tmp); - fprintf(stdout, format, GSL_REAL(*c), GSL_IMAG(*c)); + + vals[0] = rb_float_new(GSL_REAL(*c)); + vals[1] = rb_float_new(GSL_IMAG(*c)); + format = rb_sprintf("%"PRIsVALUE" %"PRIsVALUE"\n", s, s); + out = rb_str_format(2, vals, format); + fwrite(StringValuePtr(out), 1, RSTRING_LEN(out), stdout); return obj; } From ce0aeacf60fda6f1c158f5111bf03d285c9bcd95 Mon Sep 17 00:00:00 2001 From: Jakub Zakrzewski Date: Sun, 24 Sep 2017 01:05:44 +0200 Subject: [PATCH 2/2] Ruby 1.9 compatibility fix --- ext/gsl_native/complex.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/gsl_native/complex.c b/ext/gsl_native/complex.c index c3c5f1b9..8b915c42 100644 --- a/ext/gsl_native/complex.c +++ b/ext/gsl_native/complex.c @@ -173,7 +173,8 @@ static VALUE rb_gsl_complex_printf(VALUE obj, VALUE s) vals[0] = rb_float_new(GSL_REAL(*c)); vals[1] = rb_float_new(GSL_IMAG(*c)); - format = rb_sprintf("%"PRIsVALUE" %"PRIsVALUE"\n", s, s); + format = rb_sprintf("%s %s\n", STR2CSTR(s), STR2CSTR(s)); + RB_GC_GUARD(s); out = rb_str_format(2, vals, format); fwrite(StringValuePtr(out), 1, RSTRING_LEN(out), stdout); return obj;