static void err_append(const char *s) { if (rb_vm_parse_in_eval()) { VALUE err = rb_errinfo(); if (err == Qnil) { err = rb_exc_new2(rb_eSyntaxError, s); rb_set_errinfo(err); } else { VALUE str = rb_obj_as_string(err); rb_str_cat2(str, "\n"); rb_str_cat2(str, s); rb_set_errinfo(rb_exc_new3(rb_eSyntaxError, str)); } } else { VALUE err = rb_vm_current_exception(); if (err == Qnil) { err = rb_exc_new2(rb_eSyntaxError, "compile error"); rb_vm_set_current_exception(err); } rb_write_error(s); rb_write_error("\n"); } }
static int load_encoding(const char *name) { VALUE enclib = rb_sprintf("enc/%s.so", name); VALUE verbose = ruby_verbose; VALUE debug = ruby_debug; VALUE loaded; char *s = RSTRING_PTR(enclib) + 4, *e = RSTRING_END(enclib) - 3; int idx; while (s < e) { if (!ISALNUM(*s)) *s = '_'; else if (ISUPPER(*s)) *s = TOLOWER(*s); ++s; } OBJ_FREEZE(enclib); ruby_verbose = Qfalse; ruby_debug = Qfalse; loaded = rb_protect(require_enc, enclib, 0); ruby_verbose = verbose; ruby_debug = debug; rb_set_errinfo(Qnil); if (NIL_P(loaded)) return -1; if ((idx = rb_enc_registered(name)) < 0) return -1; if (enc_autoload_p(enc_table.list[idx].enc)) return -1; return idx; }
// 尝试执行脚本 VALUE ThisApp::TryEval(const char* str){ static char buffer[1024]; VALUE rc = Qnil; VALUE err; __try{ rc = rb_eval_string(str); } __except (EXCEPTION_EXECUTE_HANDLER){} if (!NIL_P(err = rb_errinfo())){ // class VALUE kclass = rb_class_path(CLASS_OF(err)); // message VALUE message = rb_obj_as_string(err); // backtrace VALUE ary = rb_funcall(err, rb_intern("backtrace"), 0); VALUE brstr = rb_funcall(ary, rb_intern("to_s"), 0); // sprintf sprintf_s(buffer, "Error: %s\n%s\nbacktrace: %s\n", StringValuePtr(kclass), StringValuePtr(message), StringValuePtr(brstr)); MessageBoxA(nullptr, buffer, "Error", MB_OK); rb_set_errinfo(Qnil); } return rc; }
static VALUE exc_equal(VALUE exc, VALUE obj) { VALUE mesg, backtrace; if (exc == obj) return Qtrue; if (rb_obj_class(exc) != rb_obj_class(obj)) { int status = 0; obj = rb_protect(try_convert_to_exception, obj, &status); if (status || obj == Qundef) { rb_set_errinfo(Qnil); return Qfalse; } if (rb_obj_class(exc) != rb_obj_class(obj)) return Qfalse; mesg = rb_check_funcall(obj, id_message, 0, 0); if (mesg == Qundef) return Qfalse; backtrace = rb_check_funcall(obj, id_backtrace, 0, 0); if (backtrace == Qundef) return Qfalse; } else { mesg = rb_attr_get(obj, id_mesg); backtrace = exc_backtrace(obj); } if (!rb_equal(rb_attr_get(exc, id_mesg), mesg)) return Qfalse; if (!rb_equal(exc_backtrace(exc), backtrace)) return Qfalse; return Qtrue; }
static int load_encoding(const char *name) { VALUE enclib = rb_sprintf("enc/%s.so", name); VALUE verbose = ruby_verbose; VALUE debug = ruby_debug; VALUE errinfo; char *s = RSTRING_PTR(enclib) + 4, *e = RSTRING_END(enclib) - 3; int loaded; int idx; while (s < e) { if (!ISALNUM(*s)) *s = '_'; else if (ISUPPER(*s)) *s = (char)TOLOWER(*s); ++s; } FL_UNSET(enclib, FL_TAINT); enclib = rb_fstring(enclib); ruby_verbose = Qfalse; ruby_debug = Qfalse; errinfo = rb_errinfo(); loaded = rb_require_internal(enclib, rb_safe_level()); ruby_verbose = verbose; ruby_debug = debug; rb_set_errinfo(errinfo); if (loaded < 0 || 1 < loaded) return -1; if ((idx = rb_enc_registered(name)) < 0) return -1; if (enc_autoload_p(enc_table.list[idx].enc)) return -1; return idx; }
int ossl_verify_cb(int ok, X509_STORE_CTX *ctx) { VALUE proc, rctx, ret; struct ossl_verify_cb_args args; int state = 0; proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, ossl_verify_cb_idx); if ((void*)proc == 0) proc = (VALUE)X509_STORE_get_ex_data(ctx->ctx, ossl_verify_cb_idx); if ((void*)proc == 0) return ok; if (!NIL_P(proc)) { ret = Qfalse; rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new, (VALUE)ctx, &state); if (state) { rb_set_errinfo(Qnil); rb_warn("StoreContext initialization failure"); } else { args.proc = proc; args.preverify_ok = ok ? Qtrue : Qfalse; args.store_ctx = rctx; ret = rb_protect((VALUE(*)(VALUE))ossl_call_verify_cb_proc, (VALUE)&args, &state); if (state) { rb_set_errinfo(Qnil); rb_warn("exception in verify_callback is ignored"); } ossl_x509stctx_clear_ptr(rctx); } if (ret == Qtrue) { X509_STORE_CTX_set_error(ctx, X509_V_OK); ok = 1; } else{ if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) { X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED); } ok = 0; } } return ok; }
int ruby_require_internal(const char *fname, unsigned int len) { struct RString fake; VALUE str = rb_setup_fake_str(&fake, fname, len, 0); int result = rb_require_internal(str, 0); rb_set_errinfo(Qnil); return result == TAG_RETURN ? 1 : result ? -1 : 0; }
int ruby_require_internal(const char *fname, unsigned int len) { struct RString fake; VALUE str = rb_setup_fake_str(&fake, fname, len, 0); int result = rb_require_internal(str, 0); if (result > 1) result = -1; rb_set_errinfo(Qnil); return result; }
/** * Print message from last exception triggered by ruby */ static void proxenet_ruby_print_last_exception() { VALUE rException, rExceptStr; rException = rb_errinfo(); /* get last exception */ rb_set_errinfo(Qnil); /* clear last exception */ rExceptStr = rb_funcall(rException, rb_intern("to_s"), 0, Qnil); xlog_ruby(LOG_ERROR, "Exception: %s\n", StringValuePtr(rExceptStr)); return; }
int ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_) { long len; int status; VALUE rflag, pass = (VALUE)pwd_; if (RTEST(pass)) { /* PEM_def_callback(buf, max_len, flag, StringValueCStr(pass)) does not * work because it does not allow NUL characters and truncates to 1024 * bytes silently if the input is over 1024 bytes */ if (RB_TYPE_P(pass, T_STRING)) { len = RSTRING_LEN(pass); if (len <= max_len) { memcpy(buf, RSTRING_PTR(pass), len); return (int)len; } } OSSL_Debug("passed data is not valid String???"); return -1; } if (!rb_block_given_p()) { return PEM_def_callback(buf, max_len, flag, NULL); } while (1) { /* * when the flag is nonzero, this passphrase * will be used to perform encryption; otherwise it will * be used to perform decryption. */ rflag = flag ? Qtrue : Qfalse; pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status); if (status) { /* ignore an exception raised. */ rb_set_errinfo(Qnil); return -1; } if (NIL_P(pass)) return -1; len = RSTRING_LEN(pass); if (len > max_len) { rb_warning("password must not be longer than %d bytes", max_len); continue; } memcpy(buf, RSTRING_PTR(pass), len); break; } return (int)len; }
/* * When any AsyncEngine handler runs a handle method having the GVL, * it must use this function, which can receive an optional VALUE parameter. */ VALUE ae_run_with_error_handler(void* function, VALUE param) { AE_TRACE(); VALUE ret, error; int error_tag; AE_ASSERT(AE_status != AE_STOPPED); if (param) ret = rb_protect(function, (VALUE)param, &error_tag); else ret = rb_protect(function, Qnil, &error_tag); /* * If an error occurs while in function() it can be due: * * - An Exception (including SystemExit), this is "rescue-able" via "rescue Exception" * and will run the "ensure" code if present. In this case rb_errinfo() returns the * exact Exception object. * * - A Thread#kill. This is NOT "rescue-able" via "rescue Exception" but it WILL run * the "ensure" code if present. In this case rb_errinfo() returns FIXNUM 8. * * So, check the class of the object returned by rb_errinfo(). If it's an Exception then * store it, release the loop and raise it. Otherwise (Thread#kill) then don't store the * exception returned by rb_errinfo() and just release the loop. Ruby will do the rest. */ if (error_tag) { // NOTE: This could return Fixnum 8: https://github.com/ibc/AsyncEngine/issues/4, // so the error handler must check it. error = rb_errinfo(); rb_set_errinfo(Qnil); // NOTE: While in RELEASING status ignore errors in user's provided callback/method. if (AE_status == AE_RELEASING) { AE_DEBUG2("error %s rescued while in RELEASING status, ignoring it", rb_obj_classname(error)); return Qnil; } else { AE_DEBUG("error %s rescued, passing it to the error handler", rb_obj_classname(error)); ae_handle_error(error); return Qnil; } } else return ret; }
/* :nodoc: */ static VALUE name_err_mesg_to_str(VALUE obj) { VALUE *ptr, mesg; TypedData_Get_Struct(obj, VALUE, &name_err_mesg_data_type, ptr); mesg = ptr[0]; if (NIL_P(mesg)) return Qnil; else { const char *desc = 0; VALUE d = 0, args[NAME_ERR_MESG_COUNT]; int state = 0; obj = ptr[1]; switch (obj) { case Qnil: desc = "nil"; break; case Qtrue: desc = "true"; break; case Qfalse: desc = "false"; break; default: d = rb_protect(rb_inspect, obj, &state); if (state) rb_set_errinfo(Qnil); if (NIL_P(d) || RSTRING_LEN(d) > 65) { d = rb_any_to_s(obj); } desc = RSTRING_PTR(d); break; } if (desc && desc[0] != '#') { d = d ? rb_str_dup(d) : rb_str_new2(desc); rb_str_cat2(d, ":"); rb_str_append(d, rb_class_name(CLASS_OF(obj))); } args[0] = mesg; args[1] = ptr[2]; args[2] = d; mesg = rb_f_sprintf(NAME_ERR_MESG_COUNT, args); } return mesg; }
VALUE ossl_str_new(const char *ptr, long len, int *pstate) { VALUE str; int state; str = rb_protect(ossl_str_new_i, len, &state); if (pstate) *pstate = state; if (state) { if (!pstate) rb_set_errinfo(Qnil); return Qnil; } if (ptr) memcpy(RSTRING_PTR(str), ptr, len); return str; }
int ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd) { int len, status = 0; VALUE rflag, pass; if (pwd || !rb_block_given_p()) return PEM_def_callback(buf, max_len, flag, pwd); while (1) { /* * when the flag is nonzero, this passphrase * will be used to perform encryption; otherwise it will * be used to perform decryption. */ rflag = flag ? Qtrue : Qfalse; pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status); if (status) { /* ignore an exception raised. */ rb_set_errinfo(Qnil); return -1; } len = RSTRING_LENINT(pass); if (len < 4) { /* 4 is OpenSSL hardcoded limit */ rb_warning("password must be longer than 4 bytes"); continue; } if (len > max_len) { rb_warning("password must be shorter then %d bytes", max_len-1); continue; } memcpy(buf, RSTRING_PTR(pass), len); break; } return len; }
VALUE exception_spec_rb_set_errinfo(VALUE self, VALUE exc) { rb_set_errinfo(exc); return Qnil; }