Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Zend/tests/exception_011.phpt
Binary file not shown.
34 changes: 27 additions & 7 deletions Zend/zend_exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -617,10 +617,26 @@ ZEND_METHOD(exception, __toString)
}

if (Z_STRLEN(message) > 0) {
len = zend_spprintf(&str, 0, "exception '%s' with message '%s' in %s:%ld\nStack trace:\n%s%s%s",
Z_OBJCE_P(exception)->name, Z_STRVAL(message), Z_STRVAL(file), Z_LVAL(line),
(trace && Z_STRLEN_P(trace)) ? Z_STRVAL_P(trace) : "#0 {main}\n",
len ? "\n\nNext " : "", prev_str);
char *prefix, *suffix;
int prefix_len, suffix_len;

prefix_len = zend_spprintf(&prefix, 0, "exception '%s' with message '",
Z_OBJCE_P(exception)->name);

suffix_len = zend_spprintf(&suffix, 0, "' in %s:%ld\nStack trace:\n%s%s%s",
Z_STRVAL(file), Z_LVAL(line),
(trace && Z_STRLEN_P(trace)) ? Z_STRVAL_P(trace) : "#0 {main}\n",
len ? "\n\nNext " : "", prev_str);

len = prefix_len + Z_STRLEN(message) + suffix_len;
str = emalloc(len + 1);
memcpy(str, prefix, prefix_len);
memcpy(str + prefix_len, Z_STRVAL(message), Z_STRLEN(message));
memcpy(str + prefix_len + Z_STRLEN(message), suffix, suffix_len);
str[len] = '\0';

efree(prefix);
efree(suffix);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't you use %Z here too?

  len = zend_spprintf(&str, 0, "exception '%s' with message '%Z' in %s:%ld\nStack trace:\n%s%s%s",
            Z_OBJCE_P(exception)->name, &message, Z_STRVAL(file), Z_LVAL(line),
            (trace && Z_STRLEN_P(trace)) ? Z_STRVAL_P(trace) : "#0 {main}\n",
            len ? "\n\nNext " : "", prev_str);

} else {
len = zend_spprintf(&str, 0, "exception '%s' in %s:%ld\nStack trace:\n%s%s%s",
Z_OBJCE_P(exception)->name, Z_STRVAL(file), Z_LVAL(line),
Expand All @@ -643,7 +659,7 @@ ZEND_METHOD(exception, __toString)

/* We store the result in the private property string so we can access
* the result in uncaught exception handlers without memleaks. */
zend_update_property_string(default_exception_ce, getThis(), "string", sizeof("string")-1, str TSRMLS_CC);
zend_update_property_stringl(default_exception_ce, getThis(), "string", sizeof("string")-1, str, len TSRMLS_CC);

RETURN_STRINGL(str, len, 0);
}
Expand Down Expand Up @@ -807,7 +823,11 @@ ZEND_API void zend_exception_error(zval *exception, int severity TSRMLS_DC) /* {
if (Z_TYPE_P(str) != IS_STRING) {
zend_error(E_WARNING, "%s::__toString() must return a string", ce_exception->name);
} else {
zend_update_property_string(default_exception_ce, exception, "string", sizeof("string")-1, EG(exception) ? ce_exception->name : Z_STRVAL_P(str) TSRMLS_CC);
if (EG(exception)) {
zend_update_property_string(default_exception_ce, exception, "string", sizeof("string")-1, ce_exception->name TSRMLS_CC);
} else {
zend_update_property_stringl(default_exception_ce, exception, "string", sizeof("string")-1, Z_STRVAL_P(str), Z_STRLEN_P(str) TSRMLS_CC);
}
}
}
zval_ptr_dtor(&str);
Expand Down Expand Up @@ -836,7 +856,7 @@ ZEND_API void zend_exception_error(zval *exception, int severity TSRMLS_DC) /* {
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));
zend_error_va(severity, (Z_STRLEN_P(file) > 0) ? Z_STRVAL_P(file) : NULL, Z_LVAL_P(line), "Uncaught %Z\n thrown", str);
} else {
zend_error(severity, "Uncaught exception '%s'", ce_exception->name);
}
Expand Down
20 changes: 15 additions & 5 deletions main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1086,24 +1086,34 @@ static void php_error_cb(int type, const char *error_filename, const uint error_
if (type == E_ERROR || type == E_PARSE) {
size_t len;
char *buf = php_escape_html_entities(buffer, buffer_len, &len, 0, ENT_COMPAT, NULL TSRMLS_CC);
php_printf("%s<br />\n<b>%s</b>: %s in <b>%s</b> on line <b>%d</b><br />\n%s", STR_PRINT(prepend_string), error_type_str, buf, error_filename, error_lineno, STR_PRINT(append_string));
php_printf("%s<br />\n<b>%s</b>: ", STR_PRINT(prepend_string), error_type_str);
PHPWRITE(buf, len);
php_printf(" in <b>%s</b> on line <b>%d</b><br />\n%s", error_filename, error_lineno, STR_PRINT(append_string));
efree(buf);
} else {
php_printf("%s<br />\n<b>%s</b>: %s in <b>%s</b> on line <b>%d</b><br />\n%s", STR_PRINT(prepend_string), error_type_str, buffer, error_filename, error_lineno, STR_PRINT(append_string));
php_printf("%s<br />\n<b>%s</b>: ", STR_PRINT(prepend_string), error_type_str);
PHPWRITE(buffer, buffer_len);
php_printf(" in <b>%s</b> on line <b>%d</b><br />\n%s", error_filename, error_lineno, STR_PRINT(append_string));
}
} else {
/* Write CLI/CGI errors to stderr if display_errors = "stderr" */
if ((!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "cgi")) &&
PG(display_errors) == PHP_DISPLAY_ERRORS_STDERR
) {
#ifdef PHP_WIN32
fprintf(stderr, "%s: %s in %s on line %d\n", error_type_str, buffer, error_filename, error_lineno);
fprintf(stderr, "%s: ", error_type_str);
fwrite(buffer, buffer_len, 1, stderr);
fprintf(stderr, " in %s on line %d\n", error_filename, error_lineno);
fflush(stderr);
#else
fprintf(stderr, "%s: %s in %s on line %d\n", error_type_str, buffer, error_filename, error_lineno);
fprintf(stderr, "%s: ", error_type_str);
fwrite(buffer, buffer_len, 1, stderr);
fprintf(stderr, " in %s on line %d\n", error_filename, error_lineno);
#endif
} else {
php_printf("%s\n%s: %s in %s on line %d\n%s", STR_PRINT(prepend_string), error_type_str, buffer, error_filename, error_lineno, STR_PRINT(append_string));
php_printf("%s\n%s: ", STR_PRINT(prepend_string), error_type_str);
PHPWRITE(buffer, buffer_len);
php_printf(" in %s on line %d\n%s", error_filename, error_lineno, STR_PRINT(append_string));
}
}
}
Expand Down