X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_api.c;h=78745ee9d0083082bf1e6095b735b081a3bb4abb;hp=acff118b1f9edd40b9d678f549a327a85e22c306;hb=f39ea2b145caa37d9614a8a437ffd3d8914b52f0;hpb=9676c81efbb8f180fa189d71a7ecb50dde4f5646 diff --git a/http_api.c b/http_api.c index acff118..78745ee 100644 --- a/http_api.c +++ b/http_api.c @@ -67,15 +67,16 @@ PHP_HTTP_API long _http_support(long feature) /* char *pretty_key(char *, size_t, zend_bool, zend_bool) */ char *_http_pretty_key(char *key, size_t key_len, zend_bool uctitle, zend_bool xhyphen) { + size_t i; + int wasalpha; + if (key && key_len) { - size_t i; - int wasalpha; - if ((wasalpha = isalpha((int) key[0]))) { - key[0] = (char) (uctitle ? toupper((int) key[0]) : tolower((int) key[0])); + if ((wasalpha = HTTP_IS_CTYPE(alpha, key[0]))) { + key[0] = (char) (uctitle ? HTTP_TO_CTYPE(upper, key[0]) : HTTP_TO_CTYPE(lower, key[0])); } for (i = 1; i < key_len; i++) { - if (isalpha((int) key[i])) { - key[i] = (char) (((!wasalpha) && uctitle) ? toupper((int) key[i]) : tolower((int) key[i])); + if (HTTP_IS_CTYPE(alpha, key[i])) { + key[i] = (char) (((!wasalpha) && uctitle) ? HTTP_TO_CTYPE(upper, key[i]) : HTTP_TO_CTYPE(lower, key[i])); wasalpha = 1; } else { if (xhyphen && (key[i] == '_')) { @@ -96,15 +97,15 @@ void _http_error_ex(long type TSRMLS_DC, long code, const char *format, ...) va_start(args, format); #ifdef ZEND_ENGINE_2 - if ((type == E_THROW) || (PG(error_handling) == EH_THROW)) { - char *message; - zend_class_entry *ce = http_exception_get_for_code(code); - - http_try { - vspprintf(&message, 0, format, args); - zend_throw_exception(ce, message, code TSRMLS_CC); - efree(message); - } http_catch(ce); + if ((type == E_THROW) || (PG(error_handling) == EH_THROW)) { + char *message; + zend_class_entry *ce = http_exception_get_for_code(code); + + http_try { + vspprintf(&message, 0, format, args); + zend_throw_exception(ce, message, code TSRMLS_CC); + efree(message); + } http_catch(PG(exception_class) ? PG(exception_class) : HTTP_EX_DEF_CE); } else #endif php_verror(NULL, "", type, format, args TSRMLS_CC); @@ -113,24 +114,15 @@ void _http_error_ex(long type TSRMLS_DC, long code, const char *format, ...) /* }}} */ #ifdef ZEND_ENGINE_2 -/* {{{ zval *http_exception_wrap(zval *, zval *, zend_class_entry *) */ -zval *_http_exception_wrap(zval *old_exception, zval *new_exception, zend_class_entry *ce TSRMLS_DC) +static inline void copy_bt_args(zval *from, zval *to TSRMLS_DC) { zval **args, **trace_0, *old_trace_0, *trace = NULL; - /* create wrapping exception if requested */ - if (!new_exception) { - MAKE_STD_ZVAL(new_exception); - object_init_ex(new_exception, ce); - zend_update_property_string(ce, new_exception, "message", lenof("message"), "Exception caused by inner exception(s)" TSRMLS_CC); - } - - /* copy bt arguments */ - if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), old_exception, "trace", lenof("trace"), 0 TSRMLS_CC))) { + if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), from, "trace", lenof("trace"), 0 TSRMLS_CC))) { if (Z_TYPE_P(trace) == IS_ARRAY && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) { old_trace_0 = *trace_0; if (Z_TYPE_PP(trace_0) == IS_ARRAY && SUCCESS == zend_hash_find(Z_ARRVAL_PP(trace_0), "args", sizeof("args"), (void *) &args)) { - if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), new_exception, "trace", lenof("trace"), 0 TSRMLS_CC))) { + if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), to, "trace", lenof("trace"), 0 TSRMLS_CC))) { if (Z_TYPE_P(trace) == IS_ARRAY && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) { ZVAL_ADDREF(*args); add_assoc_zval(*trace_0, "args", *args); @@ -139,8 +131,44 @@ zval *_http_exception_wrap(zval *old_exception, zval *new_exception, zend_class_ } } } +} + +/* {{{ zval *http_exception_wrap(zval *, zval *, zend_class_entry *) */ +zval *_http_exception_wrap(zval *old_exception, zval *new_exception, zend_class_entry *ce TSRMLS_DC) +{ + int inner = 1; + char *message; + zval *sub_exception, *tmp_exception; + + if (!new_exception) { + MAKE_STD_ZVAL(new_exception); + object_init_ex(new_exception, ce); + + zend_update_property(ce, new_exception, "innerException", lenof("innerException"), old_exception TSRMLS_CC); + copy_bt_args(old_exception, new_exception TSRMLS_CC); + + sub_exception = old_exception; + + while ((sub_exception = zend_read_property(Z_OBJCE_P(sub_exception), sub_exception, "innerException", lenof("innerException"), 0 TSRMLS_CC)) && Z_TYPE_P(sub_exception) == IS_OBJECT) { + ++inner; + } + + spprintf(&message, 0, "Exception caused by %d inner exception(s)", inner); + zend_update_property_string(ZEND_EXCEPTION_GET_DEFAULT(), new_exception, "message", lenof("message"), message TSRMLS_CC); + efree(message); + } else { + sub_exception = new_exception; + tmp_exception = new_exception; + + while ((tmp_exception = zend_read_property(Z_OBJCE_P(tmp_exception), tmp_exception, "innerException", lenof("innerException"), 0 TSRMLS_CC)) && Z_TYPE_P(tmp_exception) == IS_OBJECT) { + sub_exception = tmp_exception; + } + + zend_update_property(Z_OBJCE_P(sub_exception), sub_exception, "innerException", lenof("innerException"), old_exception TSRMLS_CC); + copy_bt_args(old_exception, new_exception TSRMLS_CC); + copy_bt_args(old_exception, sub_exception TSRMLS_CC); + } - zend_update_property(Z_OBJCE_P(new_exception), new_exception, "innerException", lenof("innerException"), old_exception TSRMLS_CC); zval_ptr_dtor(&old_exception); return new_exception; } @@ -228,8 +256,8 @@ STATUS _http_check_method_ex(const char *method, const char *methods) const char *found; if ( (found = strstr(methods, method)) && - (found == method || !isalpha(found[-1])) && - (strlen(found) >= strlen(method) && !isalpha(found[strlen(method)]))) { + (found == method || !HTTP_IS_CTYPE(alpha, found[-1])) && + (strlen(found) >= strlen(method) && !HTTP_IS_CTYPE(alpha, found[strlen(method)]))) { return SUCCESS; } return FAILURE;