PL_tainted = TAINT_NOT;
TAINT_NOT;
int modperl_callback(pTHX_ modperl_handler_t *handler, apr_pool_t *p,                     request_rec *r, server_rec *s, AV *args){    CV *cv = Nullcv;    I32 flags = G_EVAL|G_SCALAR;    dSP;    int count, status = OK;    int tainted_orig = PL_tainted;    /* handler callbacks shouldn't affect each other's taintedness     * state, so start every callback with a clear record and restore     * at the end. one of the main problems we are trying to solve is     * that when modperl_croak called (which calls perl's     * croak(Nullch) to throw an error object) it leaves the     * interprter in the tainted state (which supposedly will be fixed     * in 5.8.6) which later affects other callbacks that call eval,     * etc, which triggers perl crash with:     * Insecure dependency in eval while running setgid.     * Callback called exit.     */    PL_tainted = TAINT_NOT;        if ((status = modperl_handler_resolve(aTHX_ &handler, p, s)) != OK) {        PL_tainted = tainted_orig;        return status;    }    ENTER;SAVETMPS;    PUSHMARK(SP);    if (MpHandlerMETHOD(handler)) {        GV *gv;        if (!handler->mgv_obj) {            Perl_croak(aTHX_ "panic: %s method handler object is NULL!",                       handler->name);        }        gv = modperl_mgv_lookup(aTHX_ handler->mgv_obj);        XPUSHs(modperl_mgv_sv(gv));    }    if (args) {        I32 items = AvFILLp(args) + 1;        EXTEND(SP, items);        Copy(AvARRAY(args), SP + 1, items, SV*);        SP += items;    }    PUTBACK;    if (MpHandlerANON(handler)) {#ifdef USE_ITHREADS        /* it's possible that the interpreter that is running the anon         * cv, isn't the one that compiled it. so to be safe need to         * re-eval the deparsed form before using it.         * XXX: possible optimizations, see modperl_handler_new_anon */        SV *sv = eval_pv(handler->name, TRUE);         cv = (CV*)SvRV(sv);#else        /* the same interpreter that has compiled the anon cv is used         * to run it */        if (!handler->cv) {            SV *sv = eval_pv(handler->name, TRUE);             handler->cv = (CV*)SvRV(sv); /* cache */        }        cv = handler->cv;#endif    }    else {        GV *gv = modperl_mgv_lookup_autoload(aTHX_ handler->mgv_cv, s, p);        if (gv) {            cv = modperl_mgv_cv(gv);        }        else {                        const char *name;            modperl_mgv_t *symbol = handler->mgv_cv;                         /* XXX: need to validate *symbol */            if (symbol && symbol->name) {                name = modperl_mgv_as_string(aTHX_ symbol, p, 0);            }            else {                name = handler->name;            }                        MP_TRACE_h(MP_FUNC, "[%s %s] lookup of %s failed\n",                       modperl_pid_tid(p),                       modperl_server_desc(s, p), name);            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,                         "lookup of '%s' failed", name);            status = HTTP_INTERNAL_SERVER_ERROR;        }    }    if (status == OK) {        count = call_sv((SV*)cv, flags);        SPAGAIN;        if (count != 1) {            /* XXX can this really happen with G_EVAL|G_SCALAR? */            status = OK;        }        else {            SV *status_sv = POPs;            if (status_sv == &PL_sv_undef) {                /* ModPerl::Util::exit() and Perl_croak internally                 * arrange to return PL_sv_undef with G_EVAL|G_SCALAR */                status = OK;             }            else {                status = SvIVx(status_sv);            }        }        PUTBACK;    }        FREETMPS;LEAVE;    if (SvTRUE(ERRSV)) {        MP_TRACE_h(MP_FUNC, "$@ = %s", SvPV_nolen(ERRSV));        status = HTTP_INTERNAL_SERVER_ERROR;    }    if (status == HTTP_INTERNAL_SERVER_ERROR) {        if (r && r->notes) {            apr_table_set(r->notes, "error-notes", SvPV_nolen(ERRSV));        }    }    PL_tainted = tainted_orig;    return status;}