[前][次][番号順一覧][スレッド一覧]

ruby-changes:41003

From: nobu <ko1@a...>
Date: Sun, 13 Dec 2015 18:36:05 +0900 (JST)
Subject: [ruby-changes:41003] nobu:r53082 (trunk): function.c: check arguments

nobu	2015-12-13 18:35:58 +0900 (Sun, 13 Dec 2015)

  New Revision: 53082

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=53082

  Log:
    function.c: check arguments
    
    * ext/fiddle/function.c (initialize): check all arguments first.
      reported by Marcin 'Icewall' Noga of Cisco Talos.

  Modified files:
    trunk/ChangeLog
    trunk/ext/fiddle/function.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 53081)
+++ ChangeLog	(revision 53082)
@@ -1,4 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
-Sun Dec 13 18:35:11 2015  Nobuyoshi Nakada  <nobu@r...>
+Sun Dec 13 18:35:57 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* ext/fiddle/function.c (initialize): check all arguments first.
+	  reported by Marcin 'Icewall' Noga of Cisco Talos.
 
 	* ext/fiddle/conversions.h (PTR2NUM): use signed integer to make
 	  Fixnum for negative values.
Index: ext/fiddle/function.c
===================================================================
--- ext/fiddle/function.c	(revision 53081)
+++ ext/fiddle/function.c	(revision 53082)
@@ -15,12 +15,16 @@ VALUE cFiddleFunction; https://github.com/ruby/ruby/blob/trunk/ext/fiddle/function.c#L15
 #define MAX_ARGS (SIZE_MAX / (sizeof(void *) + sizeof(fiddle_generic)) - 1)
 
 #define Check_Max_Args(name, len) \
+    Check_Max_Args_(name, len, "")
+#define Check_Max_Args_Long(name, len) \
+    Check_Max_Args_(name, len, "l")
+#define Check_Max_Args_(name, len, fmt) \
     if ((size_t)(len) < MAX_ARGS) { \
 	/* OK */ \
     } \
     else { \
 	rb_raise(rb_eTypeError, \
-		 name" is so large that it can cause integer overflow (%d)", \
+		 name" is so large that it can cause integer overflow (%"fmt"d)", \
 		 (len)); \
     }
 
@@ -87,16 +91,34 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/ext/fiddle/function.c#L91
 initialize(int argc, VALUE argv[], VALUE self)
 {
     ffi_cif * cif;
-    ffi_type **arg_types;
+    ffi_type **arg_types, *rtype;
     ffi_status result;
     VALUE ptr, args, ret_type, abi, kwds;
-    long i;
+    long i, len;
+    int nabi;
+    void *cfunc;
 
     rb_scan_args(argc, argv, "31:", &ptr, &args, &ret_type, &abi, &kwds);
-    if(NIL_P(abi)) abi = INT2NUM(FFI_DEFAULT_ABI);
+    ptr = rb_Integer(ptr);
+    cfunc = NUM2PTR(ptr);
+    PTR2NUM(cfunc);
+    nabi = NIL_P(abi) ? FFI_DEFAULT_ABI : NUM2INT(abi);
+    abi = INT2FIX(nabi);
+    i = NUM2INT(ret_type);
+    rtype = INT2FFI_TYPE(i);
+    ret_type = INT2FIX(i);
 
     Check_Type(args, T_ARRAY);
-    Check_Max_Args("args", RARRAY_LENINT(args));
+    len = RARRAY_LENINT(args);
+    Check_Max_Args_Long("args", len);
+    ary = rb_ary_subseq(ary, 0, len);
+    for (i = 0; i < RARRAY_LEN(args); i++) {
+	VALUE a = RARRAY_PTR(args)[i];
+	int type = NUM2INT(a);
+	(void)INT2FFI_TYPE(type); /* raise */
+	if (INT2FIX(type) != a) rb_ary_store(ary, i, INT2FIX(type));
+    }
+    OBJ_FREEZE(ary);
 
     rb_iv_set(self, "@ptr", ptr);
     rb_iv_set(self, "@args", args);
@@ -107,20 +129,15 @@ initialize(int argc, VALUE argv[], VALUE https://github.com/ruby/ruby/blob/trunk/ext/fiddle/function.c#L129
 
     TypedData_Get_Struct(self, ffi_cif, &function_data_type, cif);
 
-    arg_types = xcalloc(RARRAY_LEN(args) + 1, sizeof(ffi_type *));
+    arg_types = xcalloc(len + 1, sizeof(ffi_type *));
 
     for (i = 0; i < RARRAY_LEN(args); i++) {
 	int type = NUM2INT(RARRAY_AREF(args, i));
 	arg_types[i] = INT2FFI_TYPE(type);
     }
-    arg_types[RARRAY_LEN(args)] = NULL;
+    arg_types[len] = NULL;
 
-    result = ffi_prep_cif (
-	    cif,
-	    NUM2INT(abi),
-	    RARRAY_LENINT(args),
-	    INT2FFI_TYPE(NUM2INT(ret_type)),
-	    arg_types);
+    result = ffi_prep_cif(cif, nabi, len, rtype, arg_types);
 
     if (result)
 	rb_raise(rb_eRuntimeError, "error creating CIF %d", result);
@@ -182,8 +199,9 @@ function_call(int argc, VALUE argv[], VA https://github.com/ruby/ruby/blob/trunk/ext/fiddle/function.c#L199
     for (i = 0; i < argc; i++) {
 	VALUE type = RARRAY_AREF(types, i);
 	VALUE src = argv[i];
+	int argtype = FIX2INT(type);
 
-	if(NUM2INT(type) == TYPE_VOIDP) {
+	if (argtype == TYPE_VOIDP) {
 	    if(NIL_P(src)) {
 		src = INT2FIX(0);
 	    } else if(cPointer != CLASS_OF(src)) {
@@ -192,11 +210,11 @@ function_call(int argc, VALUE argv[], VA https://github.com/ruby/ruby/blob/trunk/ext/fiddle/function.c#L210
 	    src = rb_Integer(src);
 	}
 
-	VALUE2GENERIC(NUM2INT(type), src, &generic_args[i]);
+	VALUE2GENERIC(argtype, src, &generic_args[i]);
 	args.values[i] = (void *)&generic_args[i];
     }
     args.values[argc] = NULL;
-    args.fn = NUM2PTR(rb_Integer(cfunc));
+    args.fn = NUM2PTR(cfunc);
 
     (void)rb_thread_call_without_gvl(nogvl_ffi_call, &args, 0, 0);
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]