VALUE rpm_db_transaction(int argc, VALUE* argv, VALUE db) { VALUE trans; rpm_trans_t* ts; const char* root = "/"; #if 0 if (OBJ_FROZEN(db)) { rb_error_frozen("RPM::DB"); } #endif switch (argc) { case 0: break; case 1: if (TYPE(argv[0]) != T_STRING) { rb_raise(rb_eTypeError, "illegal argument type"); } root = RSTRING_PTR(argv[0]); break; default: rb_raise(rb_eArgError, "argument too many(0..1)"); } ts = ALLOC(rpm_trans_t); #if RPM_VERSION_CODE < RPM_VERSION(4,1,0) ts->ts = rpmtransCreateSet(RPM_DB(db), root); #else ts->ts = rpmtsCreate(); rpmtsSetRootDir(ts->ts, root); #endif ts->script_fd = 0; ts->db = DATA_PTR(db); trans = Data_Wrap_Struct(rpm_cTransaction, NULL, transaction_free, ts); db_ref(ts->db); rb_ivar_set(trans, id_db, db); rb_catch("abort", transaction_yield, trans); if (rb_ivar_get(trans, id_aborted) == Qtrue) { return Qfalse; } else if (rb_ivar_get(trans, id_commited) != Qtrue && !OBJ_FROZEN(db)) { rb_catch("abort", transaction_commit, trans); } return rb_ivar_get(trans, id_pl); }
static void rb_struct_modify(VALUE s) { if (OBJ_FROZEN(s)) rb_error_frozen("Struct"); if (!OBJ_TAINTED(s) && rb_safe_level() >= 4) rb_raise(rb_eSecurityError, "Insecure: can't modify Struct"); }
VALUE rb_singleton_class(VALUE obj) { VALUE klass; if (FIXNUM_P(obj) || SYMBOL_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton"); } if (rb_special_const_p(obj)) { SPECIAL_SINGLETON(Qnil, rb_cNilClass); SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); rb_bug("unknown immediate %ld", obj); } DEFER_INTS; if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) { klass = RBASIC(obj)->klass; } else { klass = rb_make_metaclass(obj, RBASIC(obj)->klass); } if (OBJ_TAINTED(obj)) { OBJ_TAINT(klass); } else { FL_UNSET(klass, FL_TAINT); } if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); ALLOW_INTS; return klass; }
VALUE rb_singleton_class(VALUE obj) { if (FIXNUM_P(obj) || SYMBOL_P(obj) || FIXFLOAT_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton"); } if (rb_special_const_p(obj)) { SPECIAL_SINGLETON(Qnil, rb_cNilClass); SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); rb_bug("unknown immediate %ld", obj); } VALUE klass; switch (TYPE(obj)) { case T_CLASS: case T_MODULE: // FIXME we should really create a new metaclass here. klass = *(VALUE *)obj; break; default: klass = rb_make_metaclass(obj, RBASIC(obj)->klass); break; } OBJ_INFECT(klass, obj); if (OBJ_FROZEN(obj)) { OBJ_FREEZE(klass); } return klass; }
char * na_get_pointer_for_write(VALUE self) { char *ptr; narray_t *na; GetNArray(self,na); if (OBJ_FROZEN(self)) { rb_raise(rb_eRuntimeError, "cannot write to frozen NArray."); } if (NA_TYPE(na) == NARRAY_DATA_T) { ptr = NA_DATA_PTR(na); if (na->size > 0 && ptr == NULL) { rb_funcall(self, id_allocate, 0); ptr = NA_DATA_PTR(na); } } else { ptr = na_get_pointer(self); if (NA_SIZE(na) > 0 && ptr == NULL) { rb_raise(rb_eRuntimeError,"cannot write to unallocated NArray"); } } //NA_SET_LOCK(na); return ptr; }
static void remove_method(VALUE klass, ID mid) { st_data_t data; rb_method_entry_t *me = 0; if (klass == rb_cObject) { rb_secure(4); } if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(klass)) { rb_raise(rb_eSecurityError, "Insecure: can't remove method"); } if (OBJ_FROZEN(klass)) rb_error_frozen("class/module"); if (mid == object_id || mid == id__send__ || mid == idInitialize) { rb_warn("removing `%s' may cause serious problems", rb_id2name(mid)); } if (!st_lookup(RCLASS_M_TBL(klass), mid, &data) || !(me = (rb_method_entry_t *)data) || (!me->def || me->def->type == VM_METHOD_TYPE_UNDEF)) { rb_name_error(mid, "method `%s' not defined in %s", rb_id2name(mid), rb_class2name(klass)); } st_delete(RCLASS_M_TBL(klass), &mid, &data); rb_vm_check_redefinition_opt_method(me); rb_clear_cache_for_undef(klass, mid); rb_free_method_entry(me); CALL_METHOD_HOOK(klass, removed, mid); }
static VALUE rb_set_clone(VALUE rcv) { VALUE clone = rb_set_dup(rcv); if (OBJ_FROZEN(rcv)) OBJ_FREEZE(clone); return clone; }
static void rb_provide_feature(VALUE feature) { if (OBJ_FROZEN(get_loaded_features())) { rb_raise(rb_eRuntimeError, "$LOADED_FEATURES is frozen; cannot append feature"); } rb_ary_push(get_loaded_features(), feature); }
static VALUE rb_set_clone(VALUE rcv, SEL sel) { VALUE clone = rb_set_dup(rcv, 0); if (OBJ_FROZEN(rcv)) { OBJ_FREEZE(clone); } return clone; }
VALUE rhash_aset(VALUE hash, SEL sel, VALUE key, VALUE val) { rhash_modify(hash); if (TYPE(key) == T_STRING && !OBJ_FROZEN(key)) { key = rb_str_dup(key); OBJ_FREEZE(key); } st_insert(RHASH(hash)->tbl, key, val); return val; }
static VALUE rg_match_all(gint argc, VALUE *argv, VALUE self) { VALUE rb_string, rb_start_position, rb_match_options, rb_options; VALUE rb_frozen_string, rb_match_info; GMatchInfo *match_info = NULL; GError *error = NULL; const gchar *string; gssize string_len = -1; gint start_position = 0; GRegexMatchFlags match_options = 0; rb_scan_args(argc, argv, "11", &rb_string, &rb_options); rbg_scan_options(rb_options, "start_position", &rb_start_position, "match_options", &rb_match_options, NULL); if (OBJ_FROZEN(rb_string)) { rb_frozen_string = rb_string; } else { rb_frozen_string = rb_str_dup(rb_string); rb_str_freeze(rb_frozen_string); } string = RVAL2CSTR(rb_frozen_string); string_len = RSTRING_LEN(rb_frozen_string); if (!NIL_P(rb_start_position)) start_position = NUM2INT(rb_start_position); if (!NIL_P(rb_match_options)) match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options); g_regex_match_all_full(_SELF(self), string, string_len, start_position, match_options, &match_info, &error); if (error) RAISE_GERROR(error); if (!match_info) return Qnil; rb_match_info = GMATCHINFO2RVAL(match_info); g_match_info_unref(match_info); rb_iv_set(rb_match_info, "@string", rb_frozen_string); return rb_match_info; }
/* Method: Draw#clone Notes: see dup, init_copy */ VALUE Draw_clone(VALUE self) { volatile VALUE clone; clone = Draw_dup(self); if (OBJ_FROZEN(self)) { OBJ_FREEZE(clone); } return clone; }
/** * Clones this object. * * Ruby usage: * - @verbatim Draw#clone @endverbatim * * @param self this object * @return the clone * @see Draw_dup * @see Draw_init_copy */ VALUE Draw_clone(VALUE self) { VALUE clone; clone = Draw_dup(self); if (OBJ_FROZEN(self)) { OBJ_FREEZE(clone); } RB_GC_GUARD(clone); return clone; }
static VALUE thgroup_add_m(VALUE group, VALUE thread, bool check_enclose) { if (OBJ_FROZEN(group)) { rb_raise(rb_eThreadError, "can't move to the frozen thread group"); } rb_vm_thread_t *t = GetThreadPtr(thread); rb_thread_group_t *new_tg = GetThreadGroupPtr(group); if (new_tg->enclosed && check_enclose) { rb_raise(rb_eThreadError, "can't move from the enclosed thread group"); } if (t->group != Qnil) { if (OBJ_FROZEN(t->group)) { rb_raise(rb_eThreadError, "can't move from the frozen thread group"); } rb_thread_group_t *old_tg = GetThreadGroupPtr(t->group); if (old_tg->enclosed && check_enclose) { rb_raise(rb_eThreadError, "can't move from the enclosed thread group"); } thgroup_lock(old_tg); rb_ary_delete(old_tg->threads, thread); thgroup_unlock(old_tg); } thgroup_lock(new_tg); rb_ary_push(new_tg->threads, thread); thgroup_unlock(new_tg); GC_WB(&t->group, group); return group; }
static void rb_provide_feature(VALUE feature) { VALUE features; features = get_loaded_features(); if (OBJ_FROZEN(features)) { rb_raise(rb_eRuntimeError, "$LOADED_FEATURES is frozen; cannot append feature"); } rb_str_freeze(feature); rb_ary_push(features, rb_fstring(feature)); features_index_add(feature, INT2FIX(RARRAY_LEN(features)-1)); reset_loaded_features_snapshot(); }
static void remove_method(VALUE klass, ID mid) { if (klass == rb_cObject) { rb_secure(4); } if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) { rb_raise(rb_eSecurityError, "Insecure: can't remove method"); } if (OBJ_FROZEN(klass)) rb_error_frozen("class/module"); if (mid == object_id || mid == __send__ || mid == idInitialize) { rb_warn("removing `%s' may cause serious problem", rb_id2name(mid)); } SEL sel; Method m; sel = sel_registerName(rb_id2name(mid)); m = class_getInstanceMethod((Class)klass, sel); if (m == NULL) { char buf[100]; size_t len = strlen((char *)sel); if (((char *)sel)[len - 1] != ':') { snprintf(buf, sizeof buf, "%s:", (char *)sel); sel = sel_registerName(buf); m = class_getInstanceMethod((Class)klass, sel); } } if (m == NULL) { rb_name_error(mid, "method `%s' not defined in %s", rb_id2name(mid), rb_class2name(klass)); } if (rb_vm_get_method_node(method_getImplementation(m)) == NULL) { rb_warn("removing pure Objective-C method `%s' may cause serious " \ "problem", rb_id2name(mid)); } method_setImplementation(m, NULL); if (RCLASS_SINGLETON(klass)) { rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1, ID2SYM(mid)); } else { rb_funcall(klass, removed, 1, ID2SYM(mid)); } }
VALUE rb_singleton_class(VALUE obj) { VALUE klass; ID attached; if (FIXNUM_P(obj) || SYMBOL_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton"); } if (rb_special_const_p(obj)) { SPECIAL_SINGLETON(Qnil, rb_cNilClass); SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); rb_bug("unknown immediate %ld", obj); } CONST_ID(attached, "__attached__"); if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && rb_ivar_get(RBASIC(obj)->klass, attached) == obj) { klass = RBASIC(obj)->klass; } else { klass = rb_make_metaclass(obj, RBASIC(obj)->klass); } if (BUILTIN_TYPE(obj) == T_CLASS) { if (rb_iv_get(RBASIC(klass)->klass, "__attached__") != klass) make_metametaclass(klass); } if (OBJ_TAINTED(obj)) { OBJ_TAINT(klass); } else { FL_UNSET(klass, FL_TAINT); } if (OBJ_UNTRUSTED(obj)) { OBJ_UNTRUST(klass); } else { FL_UNSET(klass, FL_UNTRUSTED); } if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); return klass; }
static void remove_method(VALUE klass, ID mid) { if (klass == rb_cObject) { rb_secure(4); } if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(klass)) { rb_raise(rb_eSecurityError, "Insecure: can't remove method"); } if (OBJ_FROZEN(klass)) { rb_error_frozen("class/module"); } if (mid == object_id || mid == __send__ || mid == idInitialize) { rb_warn("removing `%s' may cause serious problem", rb_id2name(mid)); } rb_vm_remove_method((Class)klass, mid); }
static VALUE rb_obj_extend(VALUE obj, SEL sel, int argc, VALUE *argv) { if (OBJ_FROZEN(obj)) { rb_raise(rb_eRuntimeError, "cannot extend a frozen object"); } if (argc == 0) { rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)"); } for (int i = 0; i < argc; i++) { Check_Type(argv[i], T_MODULE); } while (argc--) { rb_funcall(argv[argc], rb_intern("extend_object"), 1, obj); rb_funcall(argv[argc], rb_intern("extended"), 1, obj); } return obj; }
static void remove_method(VALUE klass, ID mid) { st_data_t data; NODE *body = 0; if (klass == rb_cObject) { rb_secure(4); } if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) { rb_raise(rb_eSecurityError, "Insecure: can't remove method"); } if (OBJ_FROZEN(klass)) rb_error_frozen("class/module"); if (mid == object_id || mid == __send__ || mid == idInitialize) { rb_warn("removing `%s' may cause serious problem", rb_id2name(mid)); } if (st_lookup(RCLASS_M_TBL(klass), mid, &data)) { body = (NODE *)data; if (!body || !body->nd_body) body = 0; else { st_delete(RCLASS_M_TBL(klass), &mid, &data); } } if (!body) { rb_name_error(mid, "method `%s' not defined in %s", rb_id2name(mid), rb_class2name(klass)); } if (nd_type(body->nd_body->nd_body) == NODE_CFUNC) { rb_vm_check_redefinition_opt_method(body); } rb_clear_cache_for_undef(klass, mid); if (FL_TEST(klass, FL_SINGLETON)) { rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1, ID2SYM(mid)); } else { rb_funcall(klass, removed, 1, ID2SYM(mid)); } }
VALUE rb_ca_mask_array (VALUE self) { VALUE obj; CArray *ca; Data_Get_Struct(self, CArray, ca); ca_update_mask(ca); if ( ca->mask ) { obj = Data_Wrap_Struct(ca_class[ca->mask->obj_type], ca_mark, ca_free_nop, ca->mask); rb_ivar_set(obj, rb_intern("masked_array"), self); if ( OBJ_FROZEN(self) ) { rb_ca_freeze(obj); } return obj; } else { return INT2NUM(0); } }
void rb_frozen_class_p(VALUE klass) { const char *desc = "something(?!)"; if (OBJ_FROZEN(klass)) { if (RCLASS_SINGLETON(klass)) desc = "object"; else { switch (TYPE(klass)) { case T_MODULE: case T_ICLASS: desc = "module"; break; case T_CLASS: desc = "class"; break; } } rb_error_frozen(desc); } }
static void vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval, rb_num_t is_singleton, NODE *cref) { VALUE klass = cref->nd_clss; int noex = (int)cref->nd_visi; rb_iseq_t *miseq; GetISeqPtr(iseqval, miseq); if (NIL_P(klass)) { rb_raise(rb_eTypeError, "no class/module to add method"); } if (is_singleton) { if (FIXNUM_P(obj) || SYMBOL_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton method \"%s\" for %s", rb_id2name(id), rb_obj_classname(obj)); } if (OBJ_FROZEN(obj)) { rb_error_frozen("object"); } klass = rb_singleton_class(obj); noex = NOEX_PUBLIC; } /* dup */ COPY_CREF(miseq->cref_stack, cref); miseq->klass = klass; miseq->defined_method_id = id; rb_add_method(klass, id, VM_METHOD_TYPE_ISEQ, miseq, noex); if (!is_singleton && noex == NOEX_MODFUNC) { rb_add_method(rb_singleton_class(klass), id, VM_METHOD_TYPE_ISEQ, miseq, NOEX_PUBLIC); } INC_VM_STATE_VERSION(); }
/*! * \internal * Returns the singleton class of \a obj. Creates it if necessary. * * \note DO NOT expose the returned singleton class to * outside of class.c. * Use \ref rb_singleton_class instead for * consistency of the metaclass hierarchy. */ static VALUE singleton_class_of(VALUE obj) { VALUE klass; if (FIXNUM_P(obj) || FLONUM_P(obj) || SYMBOL_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton"); } if (SPECIAL_CONST_P(obj)) { klass = special_singleton_class_of(obj); if (NIL_P(klass)) rb_bug("unknown immediate %p", (void *)obj); return klass; } else { enum ruby_value_type type = BUILTIN_TYPE(obj); if (type == T_FLOAT || type == T_BIGNUM) { rb_raise(rb_eTypeError, "can't define singleton"); } } if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && rb_ivar_get(RBASIC(obj)->klass, id_attached) == obj) { klass = RBASIC(obj)->klass; } else { klass = rb_make_metaclass(obj, RBASIC(obj)->klass); } if (OBJ_TAINTED(obj)) { OBJ_TAINT(klass); } else { FL_UNSET(klass, FL_TAINT); } if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); return klass; }
/*! * \internal * Returns the singleton class of \a obj. Creates it if necessary. * * \note DO NOT expose the returned singleton class to * outside of class.c. * Use \ref rb_singleton_class instead for * consistency of the metaclass hierarchy. */ static VALUE singleton_class_of(VALUE obj) { VALUE klass; if (FIXNUM_P(obj) || SYMBOL_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton"); } if (rb_special_const_p(obj)) { SPECIAL_SINGLETON(Qnil, rb_cNilClass); SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); rb_bug("unknown immediate %p", (void *)obj); } if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && rb_ivar_get(RBASIC(obj)->klass, id_attached) == obj) { klass = RBASIC(obj)->klass; } else { klass = rb_make_metaclass(obj, RBASIC(obj)->klass); } if (OBJ_TAINTED(obj)) { OBJ_TAINT(klass); } else { FL_UNSET(klass, FL_TAINT); } if (OBJ_UNTRUSTED(obj)) { OBJ_UNTRUST(klass); } else { FL_UNSET(klass, FL_UNTRUSTED); } if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); return klass; }
/*RHO static*/ VALUE eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char *file, int line) { int state; VALUE result = Qundef; VALUE envval; rb_binding_t *bind = 0; rb_thread_t *th = GET_THREAD(); rb_env_t *env = NULL; rb_block_t block; volatile int parse_in_eval; volatile int mild_compile_error; if (file == 0) { file = rb_sourcefile(); line = rb_sourceline(); } parse_in_eval = th->parse_in_eval; mild_compile_error = th->mild_compile_error; PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { rb_iseq_t *iseq; volatile VALUE iseqval; if (scope != Qnil) { if (rb_obj_is_kind_of(scope, rb_cBinding)) { GetBindingPtr(scope, bind); envval = bind->env; } else { rb_raise(rb_eTypeError, "wrong argument type %s (expected Binding)", rb_obj_classname(scope)); } GetEnvPtr(envval, env); th->base_block = &env->block; } else { rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp); if (cfp != 0) { block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp); th->base_block = █ th->base_block->self = self; th->base_block->iseq = cfp->iseq; /* TODO */ } else { rb_raise(rb_eRuntimeError, "Can't eval on top of Fiber or Thread"); } } //RHO if ( TYPE(src) != T_STRING ){ iseqval = src; }else //RHO { /* make eval iseq */ th->parse_in_eval++; th->mild_compile_error++; iseqval = rb_iseq_compile(src, rb_str_new2(file), INT2FIX(line)); th->mild_compile_error--; th->parse_in_eval--; } vm_set_eval_stack(th, iseqval, cref); th->base_block = 0; if (0) { /* for debug */ printf("%s\n", RSTRING_PTR(rb_iseq_disasm(iseqval))); } /* save new env */ GetISeqPtr(iseqval, iseq); if (bind && iseq->local_size > 0) { bind->env = rb_vm_make_env_object(th, th->cfp); } /* kick */ CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max); result = vm_exec(th); } POP_TAG(); th->mild_compile_error = mild_compile_error; th->parse_in_eval = parse_in_eval; if (state) { if (state == TAG_RAISE) { VALUE errinfo = th->errinfo; if (strcmp(file, "(eval)") == 0) { VALUE mesg, errat, bt2; extern VALUE rb_get_backtrace(VALUE info); ID id_mesg; CONST_ID(id_mesg, "mesg"); errat = rb_get_backtrace(errinfo); mesg = rb_attr_get(errinfo, id_mesg); if (!NIL_P(errat) && TYPE(errat) == T_ARRAY && (bt2 = vm_backtrace(th, -2), RARRAY_LEN(bt2) > 0)) { if (!NIL_P(mesg) && TYPE(mesg) == T_STRING && !RSTRING_LEN(mesg)) { if (OBJ_FROZEN(mesg)) { VALUE m = rb_str_cat(rb_str_dup(RARRAY_PTR(errat)[0]), ": ", 2); rb_ivar_set(errinfo, id_mesg, rb_str_append(m, mesg)); } else { rb_str_update(mesg, 0, 0, rb_str_new2(": ")); rb_str_update(mesg, 0, 0, RARRAY_PTR(errat)[0]); } } RARRAY_PTR(errat)[0] = RARRAY_PTR(bt2)[0]; } } rb_exc_raise(errinfo); } JUMP_TAG(state); } return result; }
void rb_check_frozen(VALUE obj) { if (OBJ_FROZEN(obj)) rb_error_frozen(rb_obj_classname(obj)); }
void rb_add_method(VALUE klass, ID mid, NODE * node, int noex) { NODE *body; if (NIL_P(klass)) { klass = rb_cObject; } if (rb_safe_level() >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) { rb_raise(rb_eSecurityError, "Insecure: can't define method"); } if (!FL_TEST(klass, FL_SINGLETON) && node && nd_type(node) != NODE_ZSUPER && (mid == rb_intern("initialize") || mid == rb_intern("initialize_copy"))) { noex = NOEX_PRIVATE | noex; } else if (FL_TEST(klass, FL_SINGLETON) && node && nd_type(node) == NODE_CFUNC && mid == rb_intern("allocate")) { rb_warn ("defining %s.allocate is deprecated; use rb_define_alloc_func()", rb_class2name(rb_iv_get(klass, "__attached__"))); mid = ID_ALLOCATOR; } if (OBJ_FROZEN(klass)) { rb_error_frozen("class/module"); } rb_clear_cache_by_id(mid); /* * NODE_METHOD (NEW_METHOD(body, klass, vis)): * nd_body : method body // (2) // mark * nd_clss : klass // (1) // mark * nd_noex : visibility // (3) * * NODE_FBODY (NEW_FBODY(method, alias)): * nd_body : method (NODE_METHOD) // (2) // mark * nd_oid : original id // (1) * nd_cnt : alias count // (3) */ if (node) { body = NEW_FBODY(NEW_METHOD(node, klass, NOEX_WITH_SAFE(noex)), 0); } else { body = 0; } { /* check re-definition */ st_data_t data; NODE *old_node; if (st_lookup(RCLASS_M_TBL(klass), mid, &data)) { old_node = (NODE *)data; if (old_node) { if (nd_type(old_node->nd_body->nd_body) == NODE_CFUNC) { rb_vm_check_redefinition_opt_method(old_node); } if (RTEST(ruby_verbose) && node && old_node->nd_cnt == 0 && old_node->nd_body) { rb_warning("method redefined; discarding old %s", rb_id2name(mid)); } } } if (klass == rb_cObject && node && mid == idInitialize) { rb_warn("redefining Object#initialize may cause infinite loop"); } if (mid == object_id || mid == __send__) { if (node && nd_type(node) == RUBY_VM_METHOD_NODE) { rb_warn("redefining `%s' may cause serious problem", rb_id2name(mid)); } } } st_insert(RCLASS_M_TBL(klass), mid, (st_data_t) body); if (node && mid != ID_ALLOCATOR && ruby_running) { if (FL_TEST(klass, FL_SINGLETON)) { rb_funcall(rb_iv_get(klass, "__attached__"), singleton_added, 1, ID2SYM(mid)); } else { rb_funcall(klass, added, 1, ID2SYM(mid)); } } }
void rb_check_frozen(VALUE object) { if (OBJ_FROZEN(object)){ rb_jt_error("rb_check_frozen failure case not implemented"); abort(); } }
/* * call-seq: * ctx.setup => Qtrue # first time * ctx.setup => nil # thereafter * * This method is called automatically when a new SSLSocket is created. * Normally you do not need to call this method (unless you are writing an extension in C). */ static VALUE ossl_sslctx_setup(VALUE self) { SSL_CTX *ctx; X509 *cert = NULL, *client_ca = NULL; X509_STORE *store; EVP_PKEY *key = NULL; char *ca_path = NULL, *ca_file = NULL; int i, verify_mode; VALUE val; if(OBJ_FROZEN(self)) return Qnil; Data_Get_Struct(self, SSL_CTX, ctx); #if !defined(OPENSSL_NO_DH) if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){ SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback); } else{ SSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback); } #endif SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)self); val = ossl_sslctx_get_cert_store(self); if(!NIL_P(val)){ /* * WORKAROUND: * X509_STORE can count references, but * X509_STORE_free() doesn't care it. * So we won't increment it but mark it by ex_data. */ store = GetX509StorePtr(val); /* NO NEED TO DUP */ SSL_CTX_set_cert_store(ctx, store); SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1); } val = ossl_sslctx_get_extra_cert(self); if(!NIL_P(val)){ rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self); } /* private key may be bundled in certificate file. */ val = ossl_sslctx_get_cert(self); cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */ val = ossl_sslctx_get_key(self); key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */ if (cert && key) { if (!SSL_CTX_use_certificate(ctx, cert)) { /* Adds a ref => Safe to FREE */ ossl_raise(eSSLError, "SSL_CTX_use_certificate:"); } if (!SSL_CTX_use_PrivateKey(ctx, key)) { /* Adds a ref => Safe to FREE */ ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey:"); } if (!SSL_CTX_check_private_key(ctx)) { ossl_raise(eSSLError, "SSL_CTX_check_private_key:"); } } val = ossl_sslctx_get_client_ca(self); if(!NIL_P(val)){ if(TYPE(val) == T_ARRAY){ for(i = 0; i < RARRAY_LEN(val); i++){ client_ca = GetX509CertPtr(RARRAY_PTR(val)[i]); if (!SSL_CTX_add_client_CA(ctx, client_ca)){ /* Copies X509_NAME => FREE it. */ ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); } } } else{ client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */ if (!SSL_CTX_add_client_CA(ctx, client_ca)){ /* Copies X509_NAME => FREE it. */ ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); } } } val = ossl_sslctx_get_ca_file(self); ca_file = NIL_P(val) ? NULL : StringValuePtr(val); val = ossl_sslctx_get_ca_path(self); ca_path = NIL_P(val) ? NULL : StringValuePtr(val); if(ca_file || ca_path){ if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path)) rb_warning("can't set verify locations"); } val = ossl_sslctx_get_verify_mode(self); verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val); SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback); if (RTEST(ossl_sslctx_get_client_cert_cb(self))) SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb); val = ossl_sslctx_get_timeout(self); if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val)); val = ossl_sslctx_get_verify_dep(self); if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2LONG(val)); val = ossl_sslctx_get_options(self); if(!NIL_P(val)) SSL_CTX_set_options(ctx, NUM2LONG(val)); rb_obj_freeze(self); val = ossl_sslctx_get_sess_id_ctx(self); if (!NIL_P(val)){ StringValue(val); if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val), RSTRING_LEN(val))){ ossl_raise(eSSLError, "SSL_CTX_set_session_id_context:"); } } if (RTEST(rb_iv_get(self, "@session_get_cb"))) { SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb); OSSL_Debug("SSL SESSION get callback added"); } if (RTEST(rb_iv_get(self, "@session_new_cb"))) { SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb); OSSL_Debug("SSL SESSION new callback added"); } if (RTEST(rb_iv_get(self, "@session_remove_cb"))) { SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb); OSSL_Debug("SSL SESSION remove callback added"); } #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME val = rb_iv_get(self, "@servername_cb"); if (!NIL_P(val)) { SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); OSSL_Debug("SSL TLSEXT servername callback added"); } #endif return Qtrue; }