2003-03-23 04:32:24 +00:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Zend Engine |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2014-01-03 03:08:10 +00:00
| Copyright ( c ) 1998 - 2014 Zend Technologies Ltd . ( http : //www.zend.com) |
2003-03-23 04:32:24 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| This source file is subject to version 2.00 of the Zend license , |
2003-03-23 06:57:16 +00:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-10 20:04:29 +00:00
| available through the world - wide - web at the following url : |
2003-03-23 04:32:24 +00:00
| http : //www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ zend . com so we can mail you a copy immediately . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-02-12 10:38:14 +00:00
| Authors : Andi Gutmans < andi @ zend . com > |
2003-08-23 19:48:52 +00:00
| Marcus Boerger < helly @ php . net > |
2004-02-12 10:38:14 +00:00
| Sterling Hughes < sterling @ php . net > |
| Zeev Suraski < zeev @ zend . com > |
2003-03-23 04:32:24 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
/* $Id$ */
# include "zend.h"
# include "zend_API.h"
2003-08-28 20:35:54 +00:00
# include "zend_builtin_functions.h"
2003-10-22 20:04:48 +00:00
# include "zend_interfaces.h"
2004-07-15 22:21:36 +00:00
# include "zend_exceptions.h"
2008-01-21 19:39:55 +00:00
# include "zend_vm.h"
2010-04-24 13:32:30 +00:00
# include "zend_dtrace.h"
2003-03-23 04:32:24 +00:00
2012-08-02 10:44:15 +00:00
static zend_class_entry * default_exception_ce ;
static zend_class_entry * error_exception_ce ;
2003-09-05 11:40:30 +00:00
static zend_object_handlers default_exception_handlers ;
2004-04-13 15:19:21 +00:00
ZEND_API void ( * zend_throw_exception_hook ) ( zval * ex TSRMLS_DC ) ;
2003-03-23 04:32:24 +00:00
2014-02-10 06:04:30 +00:00
void zend_exception_set_previous ( zend_object * exception , zend_object * add_previous TSRMLS_DC )
2008-07-13 21:42:49 +00:00
{
2014-02-10 06:04:30 +00:00
zval tmp , * previous , zv , * pzv ;
2008-07-13 21:42:49 +00:00
2008-08-14 10:24:52 +00:00
if ( exception = = add_previous | | ! add_previous | | ! exception ) {
2008-07-13 21:42:49 +00:00
return ;
}
2014-02-10 06:04:30 +00:00
ZVAL_OBJ ( & tmp , add_previous ) ;
if ( ! instanceof_function ( Z_OBJCE ( tmp ) , default_exception_ce TSRMLS_CC ) ) {
2008-07-13 21:42:49 +00:00
zend_error ( E_ERROR , " Cannot set non exception as previous exception " ) ;
return ;
}
2014-02-10 06:04:30 +00:00
ZVAL_OBJ ( & zv , exception ) ;
pzv = & zv ;
do {
previous = zend_read_property ( default_exception_ce , pzv , " previous " , sizeof ( " previous " ) - 1 , 1 TSRMLS_CC ) ;
2008-07-13 21:42:49 +00:00
if ( Z_TYPE_P ( previous ) = = IS_NULL ) {
2014-02-10 06:04:30 +00:00
zend_update_property ( default_exception_ce , pzv , " previous " , sizeof ( " previous " ) - 1 , & tmp TSRMLS_CC ) ;
add_previous - > gc . refcount - - ;
2008-07-13 21:42:49 +00:00
return ;
}
2014-02-10 06:04:30 +00:00
pzv = previous ;
} while ( pzv & & Z_OBJ_P ( pzv ) ! = add_previous ) ;
2008-07-13 21:42:49 +00:00
}
2008-08-14 10:24:52 +00:00
void zend_exception_save ( TSRMLS_D ) /* { { { */
{
if ( EG ( prev_exception ) ) {
zend_exception_set_previous ( EG ( exception ) , EG ( prev_exception ) TSRMLS_CC ) ;
}
if ( EG ( exception ) ) {
EG ( prev_exception ) = EG ( exception ) ;
}
EG ( exception ) = NULL ;
}
/* }}} */
void zend_exception_restore ( TSRMLS_D ) /* { { { */
{
if ( EG ( prev_exception ) ) {
if ( EG ( exception ) ) {
zend_exception_set_previous ( EG ( exception ) , EG ( prev_exception ) TSRMLS_CC ) ;
} else {
EG ( exception ) = EG ( prev_exception ) ;
}
EG ( prev_exception ) = NULL ;
}
}
/* }}} */
2010-08-18 09:45:52 +00:00
void zend_throw_exception_internal ( zval * exception TSRMLS_DC ) /* { { { */
2004-02-12 10:38:14 +00:00
{
2010-04-24 13:32:30 +00:00
# ifdef HAVE_DTRACE
if ( DTRACE_EXCEPTION_THROWN_ENABLED ( ) ) {
2013-08-15 03:47:44 +00:00
const char * classname ;
zend_uint name_len ;
2010-11-17 21:41:30 +00:00
if ( exception ! = NULL ) {
2011-08-21 11:51:00 +00:00
zend_get_object_classname ( exception , & classname , & name_len TSRMLS_CC ) ;
2013-08-15 03:47:44 +00:00
DTRACE_EXCEPTION_THROWN ( ( char * ) classname ) ;
2010-11-17 21:41:30 +00:00
} else {
DTRACE_EXCEPTION_THROWN ( NULL ) ;
}
2010-04-24 13:32:30 +00:00
}
2010-04-25 19:17:16 +00:00
# endif /* HAVE_DTRACE */
2010-04-24 13:32:30 +00:00
2004-02-12 10:38:14 +00:00
if ( exception ! = NULL ) {
2014-02-10 06:04:30 +00:00
zend_object * previous = EG ( exception ) ;
zend_exception_set_previous ( Z_OBJ_P ( exception ) , EG ( exception ) TSRMLS_CC ) ;
EG ( exception ) = Z_OBJ_P ( exception ) ;
2008-08-14 10:24:52 +00:00
if ( previous ) {
return ;
}
2004-02-12 10:38:14 +00:00
}
if ( ! EG ( current_execute_data ) ) {
2011-01-16 21:24:43 +00:00
if ( EG ( exception ) ) {
zend_exception_error ( EG ( exception ) , E_ERROR TSRMLS_CC ) ;
}
2004-02-12 10:38:14 +00:00
zend_error ( E_ERROR , " Exception thrown without a stack frame " ) ;
}
2004-04-13 15:19:21 +00:00
if ( zend_throw_exception_hook ) {
zend_throw_exception_hook ( exception TSRMLS_CC ) ;
}
2004-12-07 07:46:12 +00:00
if ( EG ( current_execute_data ) - > opline = = NULL | |
( EG ( current_execute_data ) - > opline + 1 ) - > opcode = = ZEND_HANDLE_EXCEPTION ) {
2004-02-12 10:38:14 +00:00
/* no need to rethrow the exception */
return ;
}
EG ( opline_before_exception ) = EG ( current_execute_data ) - > opline ;
2008-01-21 19:39:55 +00:00
EG ( current_execute_data ) - > opline = EG ( exception_op ) ;
2004-02-12 10:38:14 +00:00
}
2007-01-18 12:20:15 +00:00
/* }}} */
2004-02-12 10:38:14 +00:00
2007-01-18 12:20:15 +00:00
ZEND_API void zend_clear_exception ( TSRMLS_D ) /* { { { */
2004-02-12 10:38:14 +00:00
{
2008-08-14 10:24:52 +00:00
if ( EG ( prev_exception ) ) {
2014-02-10 06:04:30 +00:00
2014-02-14 13:48:45 +00:00
OBJ_RELEASE ( EG ( prev_exception ) ) ;
2008-08-14 10:24:52 +00:00
EG ( prev_exception ) = NULL ;
}
2004-02-12 10:38:14 +00:00
if ( ! EG ( exception ) ) {
return ;
}
2014-02-14 13:48:45 +00:00
OBJ_RELEASE ( EG ( exception ) ) ;
2004-02-12 10:38:14 +00:00
EG ( exception ) = NULL ;
EG ( current_execute_data ) - > opline = EG ( opline_before_exception ) ;
# if ZEND_DEBUG
EG ( opline_before_exception ) = NULL ;
# endif
}
2007-01-18 12:20:15 +00:00
/* }}} */
2004-02-12 10:38:14 +00:00
2014-02-10 06:04:30 +00:00
static zend_object * zend_default_exception_new_ex ( zend_class_entry * class_type , int skip_top_traces TSRMLS_DC ) /* { { { */
2003-08-23 19:41:22 +00:00
{
2010-05-24 14:11:39 +00:00
zval obj ;
2003-08-23 19:41:22 +00:00
zend_object * object ;
2014-02-10 06:04:30 +00:00
zval trace ;
2003-08-23 19:41:22 +00:00
2014-02-10 06:04:30 +00:00
Z_OBJ ( obj ) = object = zend_objects_new ( class_type TSRMLS_CC ) ;
2006-05-09 23:53:23 +00:00
Z_OBJ_HT ( obj ) = & default_exception_handlers ;
2003-08-23 19:41:22 +00:00
2010-05-24 14:11:39 +00:00
object_properties_init ( object , class_type ) ;
2003-08-23 19:41:22 +00:00
2014-02-10 06:04:30 +00:00
zend_fetch_debug_backtrace ( & trace , skip_top_traces , 0 , 0 TSRMLS_CC ) ;
2014-02-21 12:14:42 +00:00
Z_SET_REFCOUNT ( trace , 0 ) ;
2003-08-28 20:35:54 +00:00
2004-02-10 16:08:01 +00:00
zend_update_property_string ( default_exception_ce , & obj , " file " , sizeof ( " file " ) - 1 , zend_get_executed_filename ( TSRMLS_C ) TSRMLS_CC ) ;
zend_update_property_long ( default_exception_ce , & obj , " line " , sizeof ( " line " ) - 1 , zend_get_executed_lineno ( TSRMLS_C ) TSRMLS_CC ) ;
2014-02-10 06:04:30 +00:00
zend_update_property ( default_exception_ce , & obj , " trace " , sizeof ( " trace " ) - 1 , & trace TSRMLS_CC ) ;
2003-08-23 19:41:22 +00:00
2014-02-10 06:04:30 +00:00
return object ;
2003-08-23 19:41:22 +00:00
}
2007-01-18 12:20:15 +00:00
/* }}} */
2003-08-23 19:41:22 +00:00
2014-02-10 06:04:30 +00:00
static zend_object * zend_default_exception_new ( zend_class_entry * class_type TSRMLS_DC ) /* { { { */
2004-07-15 22:21:36 +00:00
{
return zend_default_exception_new_ex ( class_type , 0 TSRMLS_CC ) ;
}
2007-01-18 12:20:15 +00:00
/* }}} */
2004-07-15 22:21:36 +00:00
2014-02-10 06:04:30 +00:00
static zend_object * zend_error_exception_new ( zend_class_entry * class_type TSRMLS_DC ) /* { { { */
2004-07-15 22:21:36 +00:00
{
return zend_default_exception_new_ex ( class_type , 2 TSRMLS_CC ) ;
}
2007-01-18 12:20:15 +00:00
/* }}} */
2004-07-20 09:24:22 +00:00
/* {{{ proto Exception Exception::__clone()
Clone the exception object */
2003-10-25 19:13:06 +00:00
ZEND_METHOD ( exception , __clone )
2003-10-25 19:07:09 +00:00
{
/* Should never be executable */
2003-10-25 19:13:06 +00:00
zend_throw_exception ( NULL , " Cannot clone object using __clone() " , 0 TSRMLS_CC ) ;
2003-10-25 19:07:09 +00:00
}
2004-07-20 09:24:22 +00:00
/* }}} */
2008-07-12 14:57:14 +00:00
/* {{{ proto Exception::__construct(string message, int code [, Exception previous])
2004-07-20 09:24:22 +00:00
Exception constructor */
2003-08-24 11:25:08 +00:00
ZEND_METHOD ( exception , __construct )
2003-03-23 04:32:24 +00:00
{
2014-02-21 12:14:42 +00:00
zend_string * message = NULL ;
2003-08-23 14:22:28 +00:00
long code = 0 ;
2008-07-12 14:57:14 +00:00
zval * object , * previous = NULL ;
2014-02-21 12:14:42 +00:00
int argc = ZEND_NUM_ARGS ( ) ;
2003-03-23 06:57:16 +00:00
2014-02-21 12:14:42 +00:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC , " |SlO! " , & message , & code , & previous , default_exception_ce ) = = FAILURE ) {
2008-07-13 21:42:49 +00:00
zend_error ( E_ERROR , " Wrong parameters for Exception([string $exception [, long $code [, Exception $previous = NULL]]]) " ) ;
2003-03-23 04:32:24 +00:00
}
object = getThis ( ) ;
2003-08-23 19:41:22 +00:00
if ( message ) {
2014-02-21 12:14:42 +00:00
zend_update_property_str ( default_exception_ce , object , " message " , sizeof ( " message " ) - 1 , message TSRMLS_CC ) ;
2003-08-23 19:41:22 +00:00
}
2003-03-23 04:32:24 +00:00
2003-08-23 19:41:22 +00:00
if ( code ) {
2004-02-10 16:08:01 +00:00
zend_update_property_long ( default_exception_ce , object , " code " , sizeof ( " code " ) - 1 , code TSRMLS_CC ) ;
2003-08-23 19:41:22 +00:00
}
2008-07-12 14:57:14 +00:00
if ( previous ) {
zend_update_property ( default_exception_ce , object , " previous " , sizeof ( " previous " ) - 1 , previous TSRMLS_CC ) ;
}
2003-03-23 04:32:24 +00:00
}
2004-07-20 09:24:22 +00:00
/* }}} */
2008-07-12 14:57:14 +00:00
/* {{{ proto ErrorException::__construct(string message, int code, int severity [, string filename [, int lineno [, Exception previous]]])
2004-07-20 09:24:22 +00:00
ErrorException constructor */
2004-07-15 22:21:36 +00:00
ZEND_METHOD ( error_exception , __construct )
{
2004-07-25 07:05:48 +00:00
char * message = NULL , * filename = NULL ;
long code = 0 , severity = E_ERROR , lineno ;
2008-07-12 14:57:14 +00:00
zval * object , * previous = NULL ;
2004-07-25 07:05:48 +00:00
int argc = ZEND_NUM_ARGS ( ) , message_len , filename_len ;
2004-07-15 22:21:36 +00:00
2008-07-13 21:42:49 +00:00
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , argc TSRMLS_CC , " |sllslO! " , & message , & message_len , & code , & severity , & filename , & filename_len , & lineno , & previous , default_exception_ce ) = = FAILURE ) {
zend_error ( E_ERROR , " Wrong parameters for ErrorException([string $exception [, long $code, [ long $severity, [ string $filename, [ long $lineno [, Exception $previous = NULL]]]]]]) " ) ;
2004-07-15 22:21:36 +00:00
}
object = getThis ( ) ;
if ( message ) {
zend_update_property_string ( default_exception_ce , object , " message " , sizeof ( " message " ) - 1 , message TSRMLS_CC ) ;
}
if ( code ) {
zend_update_property_long ( default_exception_ce , object , " code " , sizeof ( " code " ) - 1 , code TSRMLS_CC ) ;
}
2008-07-12 14:57:14 +00:00
if ( previous ) {
zend_update_property ( default_exception_ce , object , " previous " , sizeof ( " previous " ) - 1 , previous TSRMLS_CC ) ;
}
2004-07-15 22:21:36 +00:00
zend_update_property_long ( default_exception_ce , object , " severity " , sizeof ( " severity " ) - 1 , severity TSRMLS_CC ) ;
2006-05-09 23:53:23 +00:00
2004-07-25 07:05:48 +00:00
if ( argc > = 4 ) {
zend_update_property_string ( default_exception_ce , object , " file " , sizeof ( " file " ) - 1 , filename TSRMLS_CC ) ;
if ( argc < 5 ) {
2005-04-19 11:41:04 +00:00
lineno = 0 ; /* invalidate lineno */
2004-07-25 07:05:48 +00:00
}
zend_update_property_long ( default_exception_ce , object , " line " , sizeof ( " line " ) - 1 , lineno TSRMLS_CC ) ;
}
2004-07-15 22:21:36 +00:00
}
2004-07-20 09:24:22 +00:00
/* }}} */
2004-07-15 22:21:36 +00:00
2003-03-23 04:32:24 +00:00
# define DEFAULT_0_PARAMS \
2008-03-10 22:02:41 +00:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) { \
return ; \
2003-03-23 04:32:24 +00:00
}
2007-01-18 12:20:15 +00:00
static void _default_exception_get_entry ( zval * object , char * name , int name_len , zval * return_value TSRMLS_DC ) /* { { { */
2003-03-23 04:32:24 +00:00
{
2003-08-24 00:36:53 +00:00
zval * value ;
2003-03-23 04:32:24 +00:00
2004-02-10 16:08:01 +00:00
value = zend_read_property ( default_exception_ce , object , name , name_len , 0 TSRMLS_CC ) ;
2003-03-23 04:32:24 +00:00
2014-02-14 13:48:45 +00:00
ZVAL_DUP_DEREF ( return_value , value ) ;
2003-03-23 04:32:24 +00:00
}
2007-01-18 12:20:15 +00:00
/* }}} */
2004-07-20 09:24:22 +00:00
/* {{{ proto string Exception::getFile()
Get the file in which the exception occurred */
2003-09-17 10:15:00 +00:00
ZEND_METHOD ( exception , getFile )
2003-03-23 04:32:24 +00:00
{
DEFAULT_0_PARAMS ;
2003-08-24 00:36:53 +00:00
_default_exception_get_entry ( getThis ( ) , " file " , sizeof ( " file " ) - 1 , return_value TSRMLS_CC ) ;
2003-03-23 04:32:24 +00:00
}
2004-07-20 09:24:22 +00:00
/* }}} */
/* {{{ proto int Exception::getLine()
Get the line in which the exception occurred */
2003-09-17 10:15:00 +00:00
ZEND_METHOD ( exception , getLine )
2003-03-23 04:32:24 +00:00
{
DEFAULT_0_PARAMS ;
2003-08-24 00:36:53 +00:00
_default_exception_get_entry ( getThis ( ) , " line " , sizeof ( " line " ) - 1 , return_value TSRMLS_CC ) ;
2003-03-23 04:32:24 +00:00
}
2004-07-20 09:24:22 +00:00
/* }}} */
/* {{{ proto string Exception::getMessage()
Get the exception message */
2003-09-17 10:15:00 +00:00
ZEND_METHOD ( exception , getMessage )
2003-03-23 04:32:24 +00:00
{
DEFAULT_0_PARAMS ;
2003-08-24 00:36:53 +00:00
_default_exception_get_entry ( getThis ( ) , " message " , sizeof ( " message " ) - 1 , return_value TSRMLS_CC ) ;
2003-03-23 04:32:24 +00:00
}
2004-07-20 09:24:22 +00:00
/* }}} */
/* {{{ proto int Exception::getCode()
Get the exception code */
2003-09-17 10:15:00 +00:00
ZEND_METHOD ( exception , getCode )
2003-03-23 04:32:24 +00:00
{
DEFAULT_0_PARAMS ;
2003-08-24 00:36:53 +00:00
_default_exception_get_entry ( getThis ( ) , " code " , sizeof ( " code " ) - 1 , return_value TSRMLS_CC ) ;
2003-03-23 04:32:24 +00:00
}
2004-07-20 09:24:22 +00:00
/* }}} */
2003-03-23 04:32:24 +00:00
2004-07-20 09:24:22 +00:00
/* {{{ proto array Exception::getTrace()
Get the stack trace for the location in which the exception occurred */
2003-09-17 10:15:00 +00:00
ZEND_METHOD ( exception , getTrace )
2003-08-28 23:43:56 +00:00
{
DEFAULT_0_PARAMS ;
_default_exception_get_entry ( getThis ( ) , " trace " , sizeof ( " trace " ) - 1 , return_value TSRMLS_CC ) ;
}
2004-07-20 09:24:22 +00:00
/* }}} */
2003-08-28 23:43:56 +00:00
2004-07-20 10:43:19 +00:00
/* {{{ proto int ErrorException::getSeverity()
2004-07-20 09:24:22 +00:00
Get the exception severity */
2004-07-15 22:21:36 +00:00
ZEND_METHOD ( error_exception , getSeverity )
{
DEFAULT_0_PARAMS ;
_default_exception_get_entry ( getThis ( ) , " severity " , sizeof ( " severity " ) - 1 , return_value TSRMLS_CC ) ;
}
2004-07-20 09:24:22 +00:00
/* }}} */
2004-07-15 22:21:36 +00:00
2007-01-18 12:20:15 +00:00
/* {{{ gettraceasstring() macros */
2014-02-19 04:13:43 +00:00
# define TRACE_APPEND_CHR(chr) \
str = STR_REALLOC ( str , str - > len + 1 , 0 ) ; \
str - > val [ str - > len - 1 ] = chr
# define TRACE_APPEND_STRL(v, l) \
{ \
str = STR_REALLOC ( str , str - > len + ( l ) , 0 ) ; \
memcpy ( str - > val + str - > len - ( l ) , ( v ) , ( l ) ) ; \
2003-08-30 18:28:24 +00:00
}
2014-02-19 04:13:43 +00:00
# define TRACE_APPEND_STR(v) \
TRACE_APPEND_STRL ( ( v ) , sizeof ( ( v ) ) - 1 )
2003-08-30 18:28:24 +00:00
2014-02-10 06:04:30 +00:00
# define TRACE_APPEND_KEY(key) do { \
2014-02-19 04:13:43 +00:00
tmp = zend_hash_str_find ( ht , key , sizeof ( key ) - 1 ) ; \
if ( tmp ) { \
if ( Z_TYPE_P ( tmp ) ! = IS_STRING ) { \
zend_error ( E_WARNING , " Value for %s is no string " , key ) ; \
TRACE_APPEND_STR ( " [unknown] " ) ; \
2014-02-10 06:04:30 +00:00
} else { \
2014-02-19 04:13:43 +00:00
TRACE_APPEND_STRL ( Z_STRVAL_P ( tmp ) , Z_STRLEN_P ( tmp ) ) ; \
2014-02-10 06:04:30 +00:00
} \
} \
} while ( 0 )
2003-08-30 18:28:24 +00:00
2007-01-18 12:20:15 +00:00
/* }}} */
2014-02-10 06:04:30 +00:00
static int _build_trace_args ( zval * arg TSRMLS_DC , int num_args , va_list args , zend_hash_key * hash_key ) /* { { { */
2003-08-30 18:28:24 +00:00
{
2014-02-19 08:03:01 +00:00
zend_string * str , * * str_ptr ;
2003-08-30 18:28:24 +00:00
2014-02-19 08:03:01 +00:00
str_ptr = va_arg ( args , zend_string * * ) ;
str = * str_ptr ;
2003-08-30 18:28:24 +00:00
/* the trivial way would be to do:
* conver_to_string_ex ( arg ) ;
* append it and kill the now tmp arg .
* but that could cause some E_NOTICE and also damn long lines .
*/
2014-03-27 09:39:09 +00:00
ZVAL_DEREF ( arg ) ;
2014-02-10 06:04:30 +00:00
switch ( Z_TYPE_P ( arg ) ) {
2003-08-30 18:28:24 +00:00
case IS_NULL :
TRACE_APPEND_STR ( " NULL, " ) ;
break ;
2003-08-31 12:40:29 +00:00
case IS_STRING : {
int l_added ;
2003-08-30 18:28:24 +00:00
TRACE_APPEND_CHR ( ' \' ' ) ;
2014-02-10 06:04:30 +00:00
if ( Z_STRLEN_P ( arg ) > 15 ) {
TRACE_APPEND_STRL ( Z_STRVAL_P ( arg ) , 15 ) ;
2003-08-30 18:28:24 +00:00
TRACE_APPEND_STR ( " ...', " ) ;
2003-08-31 12:40:29 +00:00
l_added = 15 + 6 + 1 ; /* +1 because of while (--l_added) */
2003-08-30 18:28:24 +00:00
} else {
2014-02-10 06:04:30 +00:00
l_added = Z_STRLEN_P ( arg ) ;
TRACE_APPEND_STRL ( Z_STRVAL_P ( arg ) , l_added ) ;
2003-08-30 18:28:24 +00:00
TRACE_APPEND_STR ( " ', " ) ;
2003-08-31 12:40:29 +00:00
l_added + = 3 + 1 ;
}
while ( - - l_added ) {
2014-02-19 04:13:43 +00:00
if ( str - > val [ str - > len - l_added ] < 32 ) {
str - > val [ str - > len - l_added ] = ' ? ' ;
2003-08-31 12:40:29 +00:00
}
2003-08-30 18:28:24 +00:00
}
break ;
2003-08-31 12:40:29 +00:00
}
2003-08-30 18:28:24 +00:00
case IS_BOOL :
2014-02-10 06:04:30 +00:00
if ( Z_LVAL_P ( arg ) ) {
2003-08-30 18:28:24 +00:00
TRACE_APPEND_STR ( " true, " ) ;
} else {
TRACE_APPEND_STR ( " false, " ) ;
}
break ;
2014-02-21 18:59:51 +00:00
case IS_RESOURCE : {
long lval = Z_RES_HANDLE_P ( arg ) ;
char s_tmp [ MAX_LENGTH_OF_LONG + 1 ] ;
int l_tmp = zend_sprintf ( s_tmp , " %ld " , lval ) ; /* SAFE */
2003-08-30 18:28:24 +00:00
TRACE_APPEND_STR ( " Resource id # " ) ;
2014-02-21 18:59:51 +00:00
TRACE_APPEND_STRL ( s_tmp , l_tmp ) ;
TRACE_APPEND_STR ( " , " ) ;
break ;
}
2003-08-30 18:28:24 +00:00
case IS_LONG : {
2014-02-10 06:04:30 +00:00
long lval = Z_LVAL_P ( arg ) ;
2003-08-30 18:28:24 +00:00
char s_tmp [ MAX_LENGTH_OF_LONG + 1 ] ;
int l_tmp = zend_sprintf ( s_tmp , " %ld " , lval ) ; /* SAFE */
TRACE_APPEND_STRL ( s_tmp , l_tmp ) ;
TRACE_APPEND_STR ( " , " ) ;
break ;
}
case IS_DOUBLE : {
2014-02-10 06:04:30 +00:00
double dval = Z_DVAL_P ( arg ) ;
2003-08-30 18:28:24 +00:00
char * s_tmp ;
int l_tmp ;
s_tmp = emalloc ( MAX_LENGTH_OF_DOUBLE + EG ( precision ) + 1 ) ;
l_tmp = zend_sprintf ( s_tmp , " %.*G " , ( int ) EG ( precision ) , dval ) ; /* SAFE */
TRACE_APPEND_STRL ( s_tmp , l_tmp ) ;
/* %G already handles removing trailing zeros from the fractional part, yay */
efree ( s_tmp ) ;
TRACE_APPEND_STR ( " , " ) ;
break ;
}
case IS_ARRAY :
TRACE_APPEND_STR ( " Array, " ) ;
break ;
case IS_OBJECT : {
2014-02-10 06:04:30 +00:00
zend_string * class_name ;
2003-08-30 18:28:24 +00:00
TRACE_APPEND_STR ( " Object( " ) ;
2005-06-27 18:13:13 +00:00
2014-02-10 06:04:30 +00:00
class_name = zend_get_object_classname ( arg TSRMLS_CC ) ;
2005-06-27 18:13:13 +00:00
2014-02-10 06:04:30 +00:00
TRACE_APPEND_STRL ( class_name - > val , class_name - > len ) ;
//??? if(!dup) {
//??? efree((char*)class_name);
//??? }
2006-05-09 23:53:23 +00:00
2003-08-30 18:28:24 +00:00
TRACE_APPEND_STR ( " ), " ) ;
break ;
}
default :
break ;
}
2014-02-19 08:03:01 +00:00
* str_ptr = str ;
2003-08-30 18:28:24 +00:00
return ZEND_HASH_APPLY_KEEP ;
}
2007-01-18 12:20:15 +00:00
/* }}} */
2003-08-30 18:28:24 +00:00
2014-02-10 06:04:30 +00:00
static int _build_trace_string ( zval * frame TSRMLS_DC , int num_args , va_list args , zend_hash_key * hash_key ) /* { { { */
2003-08-30 18:28:24 +00:00
{
2014-02-19 04:13:43 +00:00
char * s_tmp ;
int len , * num ;
2003-08-30 18:28:24 +00:00
long line ;
2014-02-10 06:04:30 +00:00
HashTable * ht = Z_ARRVAL_P ( frame ) ;
zval * file , * tmp ;
2014-02-19 08:03:01 +00:00
zend_string * str , * * str_ptr ;
2003-08-30 18:28:24 +00:00
2014-02-10 06:04:30 +00:00
if ( Z_TYPE_P ( frame ) ! = IS_ARRAY ) {
2012-12-13 21:39:35 +00:00
zend_error ( E_WARNING , " Expected array for frame %lu " , hash_key - > h ) ;
return ZEND_HASH_APPLY_KEEP ;
}
2014-02-19 08:03:01 +00:00
str_ptr = va_arg ( args , zend_string * * ) ;
str = * str_ptr ;
2003-08-30 23:55:04 +00:00
num = va_arg ( args , int * ) ;
2003-08-30 18:28:24 +00:00
2003-08-31 09:35:54 +00:00
s_tmp = emalloc ( 1 + MAX_LENGTH_OF_LONG + 1 + 1 ) ;
2014-02-19 04:13:43 +00:00
len = sprintf ( s_tmp , " #%d " , ( * num ) + + ) ;
TRACE_APPEND_STRL ( s_tmp , len ) ;
2003-08-30 18:58:40 +00:00
efree ( s_tmp ) ;
2014-02-10 06:04:30 +00:00
file = zend_hash_str_find ( ht , " file " , sizeof ( " file " ) - 1 ) ;
if ( file ) {
if ( Z_TYPE_P ( file ) ! = IS_STRING ) {
2012-12-13 21:39:35 +00:00
zend_error ( E_WARNING , " Function name is no string " ) ;
TRACE_APPEND_STR ( " [unknown function] " ) ;
} else {
2014-02-10 06:04:30 +00:00
tmp = zend_hash_str_find ( ht , " line " , sizeof ( " line " ) - 1 ) ;
if ( tmp ) {
if ( Z_TYPE_P ( tmp ) = = IS_LONG ) {
line = Z_LVAL_P ( tmp ) ;
2012-12-13 21:39:35 +00:00
} else {
zend_error ( E_WARNING , " Line is no long " ) ;
line = 0 ;
}
} else {
line = 0 ;
}
2014-02-10 06:04:30 +00:00
s_tmp = emalloc ( Z_STRLEN_P ( file ) + MAX_LENGTH_OF_LONG + 4 + 1 ) ;
2014-02-19 04:13:43 +00:00
len = sprintf ( s_tmp , " %s(%ld): " , Z_STRVAL_P ( file ) , line ) ;
TRACE_APPEND_STRL ( s_tmp , len ) ;
2012-12-13 21:39:35 +00:00
efree ( s_tmp ) ;
2003-08-30 18:28:24 +00:00
}
} else {
TRACE_APPEND_STR ( " [internal function]: " ) ;
}
TRACE_APPEND_KEY ( " class " ) ;
TRACE_APPEND_KEY ( " type " ) ;
TRACE_APPEND_KEY ( " function " ) ;
TRACE_APPEND_CHR ( ' ( ' ) ;
2014-02-10 06:04:30 +00:00
tmp = zend_hash_str_find ( ht , " args " , sizeof ( " args " ) - 1 ) ;
if ( tmp ) {
if ( Z_TYPE_P ( tmp ) = = IS_ARRAY ) {
2014-02-19 04:13:43 +00:00
int last_len = str - > len ;
2014-02-19 08:03:01 +00:00
zend_hash_apply_with_arguments ( Z_ARRVAL_P ( tmp ) TSRMLS_CC , ( apply_func_args_t ) _build_trace_args , 1 , & str ) ;
2014-02-19 04:13:43 +00:00
if ( last_len ! = str - > len ) {
str - > len - = 2 ; /* remove last ', ' */
2012-12-13 21:39:35 +00:00
}
} else {
zend_error ( E_WARNING , " args element is no array " ) ;
2003-09-01 21:40:58 +00:00
}
2003-08-30 18:28:24 +00:00
}
TRACE_APPEND_STR ( " ) \n " ) ;
2014-02-19 08:03:01 +00:00
* str_ptr = str ;
2003-08-30 18:28:24 +00:00
return ZEND_HASH_APPLY_KEEP ;
}
2007-01-18 12:20:15 +00:00
/* }}} */
2004-07-20 09:24:22 +00:00
/* {{{ proto string Exception::getTraceAsString()
Obtain the backtrace for the exception as a string ( instead of an array ) */
2003-09-17 10:15:00 +00:00
ZEND_METHOD ( exception , getTraceAsString )
2003-08-30 18:28:24 +00:00
{
zval * trace ;
2014-02-19 04:13:43 +00:00
zend_string * str ;
int num = 0 , len ;
char s_tmp [ MAX_LENGTH_OF_LONG + 7 + 1 + 1 ] ;
2006-05-09 23:53:23 +00:00
2009-05-11 14:14:52 +00:00
DEFAULT_0_PARAMS ;
2009-05-11 15:03:47 +00:00
2014-02-19 04:13:43 +00:00
str = STR_ALLOC ( 0 , 0 ) ;
2009-05-11 14:14:52 +00:00
2006-07-21 08:39:30 +00:00
trace = zend_read_property ( default_exception_ce , getThis ( ) , " trace " , sizeof ( " trace " ) - 1 , 1 TSRMLS_CC ) ;
2014-02-19 08:03:01 +00:00
zend_hash_apply_with_arguments ( Z_ARRVAL_P ( trace ) TSRMLS_CC , ( apply_func_args_t ) _build_trace_string , 2 , & str , & num ) ;
2003-08-30 18:28:24 +00:00
2014-02-19 04:13:43 +00:00
len = sprintf ( s_tmp , " #%d {main} " , num ) ;
TRACE_APPEND_STRL ( s_tmp , len ) ;
str - > val [ str - > len ] = ' \0 ' ;
2003-09-01 20:54:48 +00:00
2014-02-19 04:13:43 +00:00
RETURN_STR ( str ) ;
2003-08-30 18:28:24 +00:00
}
/* }}} */
2008-07-12 14:57:14 +00:00
/* {{{ proto string Exception::getPrevious()
Return previous Exception or NULL . */
ZEND_METHOD ( exception , getPrevious )
{
zval * previous ;
2009-05-11 14:14:52 +00:00
DEFAULT_0_PARAMS ;
2008-07-12 14:57:14 +00:00
previous = zend_read_property ( default_exception_ce , getThis ( ) , " previous " , sizeof ( " previous " ) - 1 , 1 TSRMLS_CC ) ;
RETURN_ZVAL ( previous , 1 , 0 ) ;
}
2013-09-23 11:21:57 +00:00
int zend_spprintf ( char * * message , int max_len , const char * format , . . . ) /* { { { */
2003-11-29 17:03:45 +00:00
{
va_list arg ;
int len ;
2006-05-09 23:53:23 +00:00
va_start ( arg , format ) ;
2003-11-29 17:03:45 +00:00
len = zend_vspprintf ( message , max_len , format , arg ) ;
va_end ( arg ) ;
return len ;
}
2007-01-18 12:20:15 +00:00
/* }}} */
2004-07-20 09:24:22 +00:00
/* {{{ proto string Exception::__toString()
Obtain the string representation of the Exception object */
2003-10-22 19:00:42 +00:00
ZEND_METHOD ( exception , __toString )
2003-08-30 18:28:24 +00:00
{
2014-02-14 13:48:45 +00:00
zval message , file , line , trace , * exception ;
2009-05-11 15:03:47 +00:00
char * str , * prev_str ;
2008-07-12 14:57:14 +00:00
int len = 0 ;
2003-08-30 18:28:24 +00:00
zend_fcall_info fci ;
zval fname ;
2009-05-11 14:14:52 +00:00
DEFAULT_0_PARAMS ;
2009-05-11 15:03:47 +00:00
str = estrndup ( " " , 0 ) ;
2004-02-10 16:08:01 +00:00
2008-07-12 14:57:14 +00:00
exception = getThis ( ) ;
2014-02-10 06:04:30 +00:00
ZVAL_STRINGL ( & fname , " gettraceasstring " , sizeof ( " gettraceasstring " ) - 1 ) ;
2003-08-30 18:28:24 +00:00
2008-07-12 14:57:14 +00:00
while ( exception & & Z_TYPE_P ( exception ) = = IS_OBJECT ) {
prev_str = str ;
_default_exception_get_entry ( exception , " message " , sizeof ( " message " ) - 1 , & message TSRMLS_CC ) ;
_default_exception_get_entry ( exception , " file " , sizeof ( " file " ) - 1 , & file TSRMLS_CC ) ;
_default_exception_get_entry ( exception , " line " , sizeof ( " line " ) - 1 , & line TSRMLS_CC ) ;
convert_to_string ( & message ) ;
convert_to_string ( & file ) ;
convert_to_long ( & line ) ;
fci . size = sizeof ( fci ) ;
fci . function_table = & Z_OBJCE_P ( exception ) - > function_table ;
2014-02-10 06:04:30 +00:00
ZVAL_COPY_VALUE ( & fci . function_name , & fname ) ;
2008-07-12 14:57:14 +00:00
fci . symbol_table = NULL ;
2008-11-27 19:01:23 +00:00
fci . object_ptr = exception ;
2014-02-14 13:48:45 +00:00
fci . retval = & trace ;
2008-07-12 14:57:14 +00:00
fci . param_count = 0 ;
fci . params = NULL ;
fci . no_separation = 1 ;
zend_call_function ( & fci , NULL TSRMLS_CC ) ;
2014-02-14 13:48:45 +00:00
if ( Z_TYPE ( trace ) ! = IS_STRING ) {
zval_ptr_dtor ( & trace ) ;
ZVAL_UNDEF ( & trace ) ;
}
2003-08-30 18:28:24 +00:00
2008-07-12 14:57:14 +00:00
if ( Z_STRLEN ( message ) > 0 ) {
len = zend_spprintf ( & str , 0 , " exception '%s' with message '%s' in %s:%ld \n Stack trace: \n %s%s%s " ,
2014-02-19 08:03:01 +00:00
Z_OBJCE_P ( exception ) - > name - > val , Z_STRVAL ( message ) , Z_STRVAL ( file ) , Z_LVAL ( line ) ,
2014-02-14 13:48:45 +00:00
( Z_TYPE ( trace ) = = IS_STRING & & Z_STRLEN ( trace ) ) ? Z_STRVAL ( trace ) : " #0 {main} \n " ,
2008-07-12 14:57:14 +00:00
len ? " \n \n Next " : " " , prev_str ) ;
} else {
len = zend_spprintf ( & str , 0 , " exception '%s' in %s:%ld \n Stack trace: \n %s%s%s " ,
2014-02-19 08:03:01 +00:00
Z_OBJCE_P ( exception ) - > name - > val , Z_STRVAL ( file ) , Z_LVAL ( line ) ,
2014-02-14 13:48:45 +00:00
( Z_TYPE ( trace ) = = IS_STRING & & Z_STRLEN ( trace ) ) ? Z_STRVAL ( trace ) : " #0 {main} \n " ,
2008-07-12 14:57:14 +00:00
len ? " \n \n Next " : " " , prev_str ) ;
}
efree ( prev_str ) ;
zval_dtor ( & message ) ;
zval_dtor ( & file ) ;
zval_dtor ( & line ) ;
2004-02-10 16:08:01 +00:00
2008-07-12 14:57:14 +00:00
exception = zend_read_property ( default_exception_ce , exception , " previous " , sizeof ( " previous " ) - 1 , 0 TSRMLS_CC ) ;
2010-08-16 08:11:08 +00:00
2014-02-14 13:48:45 +00:00
zval_ptr_dtor ( & trace ) ;
2010-08-16 08:11:08 +00:00
2004-01-02 19:27:02 +00:00
}
2008-07-13 09:32:46 +00:00
zval_dtor ( & fname ) ;
2003-08-30 18:28:24 +00:00
/* We store the result in the private property string so we can access
* the result in uncaught exception handlers without memleaks . */
2004-02-10 16:08:01 +00:00
zend_update_property_string ( default_exception_ce , getThis ( ) , " string " , sizeof ( " string " ) - 1 , str TSRMLS_CC ) ;
2014-02-10 06:04:30 +00:00
//??? RETURN_STRINGL(str, len, 0);
2014-02-26 13:36:39 +00:00
RETVAL_STRINGL ( str , len ) ;
efree ( str ) ;
2003-08-30 18:28:24 +00:00
}
2004-07-20 09:24:22 +00:00
/* }}} */
2003-08-30 18:28:24 +00:00
2007-01-18 12:20:15 +00:00
/* {{{ internal structs */
2003-08-30 11:33:41 +00:00
/* All functions that may be used in uncaught exception handlers must be final
* and must not throw exceptions . Otherwise we would need a facility to handle
2006-05-09 23:53:23 +00:00
* such exceptions in that handler .
2003-09-01 20:02:47 +00:00
* Also all getXY ( ) methods are final because thy serve as read only access to
2006-05-09 23:53:23 +00:00
* their corresponding properties , no more , no less . If after all you need to
2003-10-22 19:00:42 +00:00
* override somthing then it is method __toString ( ) .
2003-09-01 20:02:47 +00:00
* And never try to change the state of exceptions and never implement anything
* that gives the user anything to accomplish this .
2003-08-30 11:33:41 +00:00
*/
2006-06-13 20:57:35 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_exception___construct , 0 , 0 , 0 )
2004-07-15 22:21:36 +00:00
ZEND_ARG_INFO ( 0 , message )
ZEND_ARG_INFO ( 0 , code )
2008-07-12 14:59:46 +00:00
ZEND_ARG_INFO ( 0 , previous )
2007-05-30 16:32:02 +00:00
ZEND_END_ARG_INFO ( )
2004-07-15 22:21:36 +00:00
2007-09-27 18:00:48 +00:00
const static zend_function_entry default_exception_functions [ ] = {
2003-10-25 19:07:09 +00:00
ZEND_ME ( exception , __clone , NULL , ZEND_ACC_PRIVATE | ZEND_ACC_FINAL )
2004-07-27 16:21:56 +00:00
ZEND_ME ( exception , __construct , arginfo_exception___construct , ZEND_ACC_PUBLIC )
2003-09-17 10:15:00 +00:00
ZEND_ME ( exception , getMessage , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
ZEND_ME ( exception , getCode , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
ZEND_ME ( exception , getFile , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
ZEND_ME ( exception , getLine , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
ZEND_ME ( exception , getTrace , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
2008-07-12 14:57:14 +00:00
ZEND_ME ( exception , getPrevious , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
2003-09-17 10:15:00 +00:00
ZEND_ME ( exception , getTraceAsString , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
2003-10-22 19:00:42 +00:00
ZEND_ME ( exception , __toString , NULL , 0 )
2003-03-23 04:32:24 +00:00
{ NULL , NULL , NULL }
} ;
2006-06-13 20:57:35 +00:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_error_exception___construct , 0 , 0 , 0 )
2004-07-15 22:21:36 +00:00
ZEND_ARG_INFO ( 0 , message )
ZEND_ARG_INFO ( 0 , code )
ZEND_ARG_INFO ( 0 , severity )
2004-07-25 07:05:48 +00:00
ZEND_ARG_INFO ( 0 , filename )
ZEND_ARG_INFO ( 0 , lineno )
2008-07-12 14:57:14 +00:00
ZEND_ARG_INFO ( 0 , previous )
2007-05-30 16:32:02 +00:00
ZEND_END_ARG_INFO ( )
2004-07-15 22:21:36 +00:00
2007-09-27 18:00:48 +00:00
static const zend_function_entry error_exception_functions [ ] = {
2004-07-27 16:21:56 +00:00
ZEND_ME ( error_exception , __construct , arginfo_error_exception___construct , ZEND_ACC_PUBLIC )
2004-07-15 22:21:36 +00:00
ZEND_ME ( error_exception , getSeverity , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_FINAL )
{ NULL , NULL , NULL }
} ;
2007-01-18 12:20:15 +00:00
/* }}} */
2004-07-15 22:21:36 +00:00
2007-01-18 12:20:15 +00:00
void zend_register_default_exception ( TSRMLS_D ) /* { { { */
2003-03-23 04:32:24 +00:00
{
2003-08-30 11:40:37 +00:00
zend_class_entry ce ;
2003-03-23 04:32:24 +00:00
2004-04-13 20:25:49 +00:00
INIT_CLASS_ENTRY ( ce , " Exception " , default_exception_functions ) ;
2004-02-10 16:08:01 +00:00
default_exception_ce = zend_register_internal_class ( & ce TSRMLS_CC ) ;
2006-05-09 23:53:23 +00:00
default_exception_ce - > create_object = zend_default_exception_new ;
2003-09-05 11:40:30 +00:00
memcpy ( & default_exception_handlers , zend_get_std_object_handlers ( ) , sizeof ( zend_object_handlers ) ) ;
2003-10-25 19:28:31 +00:00
default_exception_handlers . clone_obj = NULL ;
2003-08-23 19:41:22 +00:00
2004-02-10 16:08:01 +00:00
zend_declare_property_string ( default_exception_ce , " message " , sizeof ( " message " ) - 1 , " " , ZEND_ACC_PROTECTED TSRMLS_CC ) ;
zend_declare_property_string ( default_exception_ce , " string " , sizeof ( " string " ) - 1 , " " , ZEND_ACC_PRIVATE TSRMLS_CC ) ;
zend_declare_property_long ( default_exception_ce , " code " , sizeof ( " code " ) - 1 , 0 , ZEND_ACC_PROTECTED TSRMLS_CC ) ;
zend_declare_property_null ( default_exception_ce , " file " , sizeof ( " file " ) - 1 , ZEND_ACC_PROTECTED TSRMLS_CC ) ;
zend_declare_property_null ( default_exception_ce , " line " , sizeof ( " line " ) - 1 , ZEND_ACC_PROTECTED TSRMLS_CC ) ;
zend_declare_property_null ( default_exception_ce , " trace " , sizeof ( " trace " ) - 1 , ZEND_ACC_PRIVATE TSRMLS_CC ) ;
2008-07-12 14:57:14 +00:00
zend_declare_property_null ( default_exception_ce , " previous " , sizeof ( " previous " ) - 1 , ZEND_ACC_PRIVATE TSRMLS_CC ) ;
2004-07-15 22:21:36 +00:00
INIT_CLASS_ENTRY ( ce , " ErrorException " , error_exception_functions ) ;
2014-02-10 06:04:30 +00:00
error_exception_ce = zend_register_internal_class_ex ( & ce , default_exception_ce TSRMLS_CC ) ;
2006-05-09 23:53:23 +00:00
error_exception_ce - > create_object = zend_error_exception_new ;
2004-07-15 22:21:36 +00:00
zend_declare_property_long ( error_exception_ce , " severity " , sizeof ( " severity " ) - 1 , E_ERROR , ZEND_ACC_PROTECTED TSRMLS_CC ) ;
2003-03-23 04:32:24 +00:00
}
2007-01-18 12:20:15 +00:00
/* }}} */
2003-03-23 04:32:24 +00:00
2007-01-18 12:20:15 +00:00
ZEND_API zend_class_entry * zend_exception_get_default ( TSRMLS_D ) /* { { { */
2003-05-03 23:54:57 +00:00
{
2004-02-10 16:08:01 +00:00
return default_exception_ce ;
2003-05-03 23:54:57 +00:00
}
2007-01-18 12:20:15 +00:00
/* }}} */
2003-05-03 23:54:57 +00:00
2007-01-18 12:20:15 +00:00
ZEND_API zend_class_entry * zend_get_error_exception ( TSRMLS_D ) /* { { { */
2003-08-28 22:56:41 +00:00
{
2004-07-15 22:21:36 +00:00
return error_exception_ce ;
}
2007-01-18 12:20:15 +00:00
/* }}} */
2003-08-31 09:35:54 +00:00
2014-02-10 06:04:30 +00:00
ZEND_API zend_object * zend_throw_exception ( zend_class_entry * exception_ce , const char * message , long code TSRMLS_DC ) /* { { { */
2004-07-15 22:21:36 +00:00
{
2014-02-10 06:04:30 +00:00
zval ex ;
2003-08-28 22:56:41 +00:00
if ( exception_ce ) {
2004-02-10 16:08:01 +00:00
if ( ! instanceof_function ( exception_ce , default_exception_ce TSRMLS_CC ) ) {
2004-02-25 13:11:00 +00:00
zend_error ( E_NOTICE , " Exceptions must be derived from the Exception base class " ) ;
2004-02-10 16:08:01 +00:00
exception_ce = default_exception_ce ;
2003-08-28 22:56:41 +00:00
}
} else {
2004-02-10 16:08:01 +00:00
exception_ce = default_exception_ce ;
2003-08-28 22:56:41 +00:00
}
2014-02-10 06:04:30 +00:00
object_init_ex ( & ex , exception_ce ) ;
2006-05-09 23:53:23 +00:00
2003-08-28 22:56:41 +00:00
if ( message ) {
2014-02-10 06:04:30 +00:00
zend_update_property_string ( default_exception_ce , & ex , " message " , sizeof ( " message " ) - 1 , message TSRMLS_CC ) ;
2003-08-28 22:56:41 +00:00
}
if ( code ) {
2014-02-10 06:04:30 +00:00
zend_update_property_long ( default_exception_ce , & ex , " code " , sizeof ( " code " ) - 1 , code TSRMLS_CC ) ;
2003-08-28 22:56:41 +00:00
}
2014-02-10 06:04:30 +00:00
zend_throw_exception_internal ( & ex TSRMLS_CC ) ;
return Z_OBJ ( ex ) ;
2003-08-28 22:56:41 +00:00
}
2007-01-18 12:20:15 +00:00
/* }}} */
2003-08-28 22:56:41 +00:00
2014-02-10 06:04:30 +00:00
ZEND_API zend_object * zend_throw_exception_ex ( zend_class_entry * exception_ce , long code TSRMLS_DC , const char * format , . . . ) /* { { { */
2003-08-21 23:32:13 +00:00
{
2004-07-15 22:21:36 +00:00
va_list arg ;
char * message ;
2014-02-10 06:04:30 +00:00
zend_object * obj ;
2004-07-15 22:21:36 +00:00
2006-05-09 23:53:23 +00:00
va_start ( arg , format ) ;
2004-07-15 22:21:36 +00:00
zend_vspprintf ( & message , 0 , format , arg ) ;
va_end ( arg ) ;
2014-02-10 06:04:30 +00:00
obj = zend_throw_exception ( exception_ce , message , code TSRMLS_CC ) ;
2004-09-27 22:06:10 +00:00
efree ( message ) ;
2014-02-10 06:04:30 +00:00
return obj ;
2003-08-21 23:32:13 +00:00
}
2007-01-18 12:20:15 +00:00
/* }}} */
2003-08-21 23:32:13 +00:00
2014-02-10 06:04:30 +00:00
ZEND_API zend_object * zend_throw_error_exception ( zend_class_entry * exception_ce , const char * message , long code , int severity TSRMLS_DC ) /* { { { */
2004-07-15 22:21:36 +00:00
{
2014-02-10 06:04:30 +00:00
zval ex ;
zend_object * obj = zend_throw_exception ( exception_ce , message , code TSRMLS_CC ) ;
ZVAL_OBJ ( & ex , obj ) ;
zend_update_property_long ( default_exception_ce , & ex , " severity " , sizeof ( " severity " ) - 1 , severity TSRMLS_CC ) ;
return obj ;
2004-07-15 22:21:36 +00:00
}
2007-01-18 12:20:15 +00:00
/* }}} */
2004-07-15 22:21:36 +00:00
2007-01-18 12:20:15 +00:00
static void zend_error_va ( int type , const char * file , uint lineno , const char * format , . . . ) /* { { { */
2003-08-24 13:10:03 +00:00
{
va_list args ;
2006-05-09 23:53:23 +00:00
2003-08-24 13:10:03 +00:00
va_start ( args , format ) ;
2003-09-11 10:26:47 +00:00
zend_error_cb ( type , file , lineno , format , args ) ;
2003-08-24 13:10:03 +00:00
va_end ( args ) ;
}
2007-01-18 12:20:15 +00:00
/* }}} */
2003-08-24 13:10:03 +00:00
2009-01-02 13:14:49 +00:00
/* This function doesn't return if it uses E_ERROR */
2014-02-10 06:04:30 +00:00
ZEND_API void zend_exception_error ( zend_object * ex , int severity TSRMLS_DC ) /* { { { */
2003-08-24 13:10:03 +00:00
{
2014-02-10 06:04:30 +00:00
zval exception ;
zend_class_entry * ce_exception ;
ZVAL_OBJ ( & exception , ex ) ;
ce_exception = Z_OBJCE ( exception ) ;
2004-02-10 16:08:01 +00:00
if ( instanceof_function ( ce_exception , default_exception_ce TSRMLS_CC ) ) {
2014-02-10 06:04:30 +00:00
zval tmp , * str , * file , * line ;
2003-08-30 18:58:40 +00:00
2003-11-29 17:03:45 +00:00
EG ( exception ) = NULL ;
2006-05-09 23:53:23 +00:00
2014-02-10 06:04:30 +00:00
zend_call_method_with_0_params ( & exception , ce_exception , NULL , " __tostring " , & tmp ) ;
2003-12-06 18:12:26 +00:00
if ( ! EG ( exception ) ) {
2014-02-10 06:04:30 +00:00
if ( Z_TYPE ( tmp ) ! = IS_STRING ) {
zend_error ( E_WARNING , " %s::__toString() must return a string " , ce_exception - > name - > val ) ;
2003-12-06 18:12:26 +00:00
} else {
2014-02-10 06:04:30 +00:00
zend_update_property_string ( default_exception_ce , & exception , " string " , sizeof ( " string " ) - 1 , EG ( exception ) ? ce_exception - > name - > val : Z_STRVAL ( tmp ) TSRMLS_CC ) ;
2003-12-06 18:12:26 +00:00
}
2003-12-05 01:44:45 +00:00
}
2014-02-10 06:04:30 +00:00
zval_ptr_dtor ( & tmp ) ;
2006-05-09 23:53:23 +00:00
2003-11-29 17:03:45 +00:00
if ( EG ( exception ) ) {
2014-02-10 06:04:30 +00:00
zval zv ;
ZVAL_OBJ ( & zv , EG ( exception ) ) ;
2003-11-29 17:03:45 +00:00
/* do the best we can to inform about the inner exception */
2004-02-10 16:08:01 +00:00
if ( instanceof_function ( ce_exception , default_exception_ce TSRMLS_CC ) ) {
2014-02-10 06:04:30 +00:00
file = zend_read_property ( default_exception_ce , & zv , " file " , sizeof ( " file " ) - 1 , 1 TSRMLS_CC ) ;
line = zend_read_property ( default_exception_ce , & zv , " line " , sizeof ( " line " ) - 1 , 1 TSRMLS_CC ) ;
2013-05-12 12:00:32 +00:00
convert_to_string ( file ) ;
file = ( Z_STRLEN_P ( file ) > 0 ) ? file : NULL ;
line = ( Z_TYPE_P ( line ) = = IS_LONG ) ? line : NULL ;
2003-11-29 17:03:45 +00:00
} else {
file = NULL ;
line = NULL ;
}
2014-02-10 06:04:30 +00:00
zend_error_va ( E_WARNING , file ? Z_STRVAL_P ( file ) : NULL , line ? Z_LVAL_P ( line ) : 0 , " Uncaught %s in exception handling during call to %s::__tostring() " , Z_OBJCE ( zv ) - > name - > val , ce_exception - > name - > val ) ;
2003-11-29 17:03:45 +00:00
}
2014-02-10 06:04:30 +00:00
str = zend_read_property ( default_exception_ce , & exception , " string " , sizeof ( " string " ) - 1 , 1 TSRMLS_CC ) ;
file = zend_read_property ( default_exception_ce , & exception , " file " , sizeof ( " file " ) - 1 , 1 TSRMLS_CC ) ;
line = zend_read_property ( default_exception_ce , & exception , " line " , sizeof ( " line " ) - 1 , 1 TSRMLS_CC ) ;
2003-11-29 17:03:45 +00:00
2013-05-12 12:00:32 +00:00
convert_to_string ( str ) ;
convert_to_string ( file ) ;
convert_to_long ( line ) ;
zend_error_va ( severity , ( Z_STRLEN_P ( file ) > 0 ) ? Z_STRVAL_P ( file ) : NULL , Z_LVAL_P ( line ) , " Uncaught %s \n thrown " , Z_STRVAL_P ( str ) ) ;
2003-08-24 13:10:03 +00:00
} else {
2014-02-10 06:04:30 +00:00
zend_error ( severity , " Uncaught exception '%s' " , ce_exception - > name - > val ) ;
2003-08-24 13:10:03 +00:00
}
}
2007-01-18 12:20:15 +00:00
/* }}} */
2003-08-24 13:10:03 +00:00
2007-01-18 12:20:15 +00:00
ZEND_API void zend_throw_exception_object ( zval * exception TSRMLS_DC ) /* { { { */
2004-02-12 10:24:40 +00:00
{
zend_class_entry * exception_ce ;
2006-05-09 23:53:23 +00:00
if ( exception = = NULL | | Z_TYPE_P ( exception ) ! = IS_OBJECT ) {
2004-02-12 10:24:40 +00:00
zend_error ( E_ERROR , " Need to supply an object when throwing an exception " ) ;
}
exception_ce = Z_OBJCE_P ( exception ) ;
if ( ! exception_ce | | ! instanceof_function ( exception_ce , default_exception_ce TSRMLS_CC ) ) {
2004-02-25 13:11:00 +00:00
zend_error ( E_ERROR , " Exceptions must be valid objects derived from the Exception base class " ) ;
2004-02-12 10:24:40 +00:00
}
zend_throw_exception_internal ( exception TSRMLS_CC ) ;
}
2007-01-18 12:20:15 +00:00
/* }}} */
2004-02-12 10:24:40 +00:00
2003-03-23 04:32:24 +00:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* indent - tabs - mode : t
* End :
*/