Ticket #1078: never_ending_exception.patch

File never_ending_exception.patch, 2.3 KB (added by NotFound, 5 years ago)

patch that limits the number of invocations of an exception handler

  • src/pmc/exceptionhandler.pmc

     
    2222 
    2323#include "parrot/oplib/ops.h" 
    2424 
     25/* Arbitrarily choosen value */ 
     26#define HANDLING_COUNTER_LIMIT 512 
     27 
    2528pmclass ExceptionHandler extends Continuation auto_attrs { 
    2629 
    2730    ATTR PMC    *handled_types; 
    2831    ATTR PMC    *handled_types_except; 
    2932    ATTR INTVAL min_severity; 
    3033    ATTR INTVAL max_severity; 
     34    ATTR INTVAL handling_counter; 
    3135 
    3236/* 
    3337 
     
    120124 
    121125    VTABLE opcode_t *invoke(void *next) { 
    122126        opcode_t    * const pc = PARROT_CONTINUATION(SELF)->address; 
     127        INTVAL counter; 
     128        GET_ATTR_handling_counter(INTERP, SELF, counter); 
     129        ++counter; 
     130        SET_ATTR_handling_counter(INTERP, SELF, counter); 
    123131 
    124132        Parrot_continuation_check(interp, SELF); 
    125133        Parrot_continuation_rewind_environment(interp, SELF); 
     
    158166        STRING * const sev    = CONST_STRING(interp, "severity"); 
    159167        STRING * const ex_str = CONST_STRING(interp, "Exception"); 
    160168 
    161         INTVAL severity = VTABLE_get_integer_keyed_str(interp, exception, sev); 
     169        const INTVAL severity = VTABLE_get_integer_keyed_str(interp, exception, sev); 
     170        const INTVAL type  = VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "type")); 
    162171 
     172        /* Declare that it can't handle any exception after reaching the limit, 
     173         * giving opportunity to other handler to take control. 
     174         * Avoid control exceptions, that are supposed to be less error prone 
     175         * and might need longer usages. */ 
     176        INTVAL counter; 
     177        GET_ATTR_handling_counter(INTERP, SELF, counter); 
     178        if (type < CONTROL_RETURN && counter >= HANDLING_COUNTER_LIMIT) 
     179            RETURN(INTVAL 0); 
     180 
    163181        if (exception->vtable->base_type == enum_class_Exception 
    164182        ||  VTABLE_isa(INTERP, exception, ex_str)) { 
    165183            PMC *handled_types; 
     
    178196            } 
    179197            if (! PMC_IS_NULL(handled_types)) { 
    180198                const INTVAL elems = VTABLE_elements(interp, handled_types); 
    181                 const INTVAL type  = VTABLE_get_integer_keyed_str(interp, exception, CONST_STRING(interp, "type")); 
    182199                INTVAL i; 
    183200 
    184201                for (i = 0; i < elems; i++) {