Merge branch '2.7' into 2.8
* 2.7: [HttpFoundation] Support 0 bit netmask in IPv6 () Set `width: auto` on WebProfiler toolbar's reset. [HttpKernel] Fix logging of post-terminate errors/exceptions [Debug] Fix catching fatal errors in case of nested error handlers Fix hidden currency element with Bootstrap 3 theme
This commit is contained in:
commit
eddd273351
@ -20,16 +20,21 @@
|
||||
{%- endblock %}
|
||||
|
||||
{% block money_widget -%}
|
||||
<div class="input-group">
|
||||
{% set append = money_pattern starts with '{{' %}
|
||||
{% if not append %}
|
||||
<span class="input-group-addon">{{ money_pattern|replace({ '{{ widget }}':''}) }}</span>
|
||||
{% endif %}
|
||||
{% set prepend = not (money_pattern starts with '{{') %}
|
||||
{% set append = not (money_pattern ends with '}}') %}
|
||||
{% if prepend or append %}
|
||||
<div class="input-group">
|
||||
{% if prepend %}
|
||||
<span class="input-group-addon">{{ money_pattern|replace({ '{{ widget }}':''}) }}</span>
|
||||
{% endif %}
|
||||
{{- block('form_widget_simple') -}}
|
||||
{% if append %}
|
||||
<span class="input-group-addon">{{ money_pattern|replace({ '{{ widget }}':''}) }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
{{- block('form_widget_simple') -}}
|
||||
{% if append %}
|
||||
<span class="input-group-addon">{{ money_pattern|replace({ '{{ widget }}':''}) }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{%- endblock money_widget %}
|
||||
|
||||
{% block percent_widget -%}
|
||||
|
@ -31,6 +31,7 @@
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
vertical-align: baseline;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.sf-toolbarreset {
|
||||
|
@ -555,6 +555,7 @@ class ErrorHandler
|
||||
$exception = new FatalThrowableError($exception);
|
||||
}
|
||||
$type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR;
|
||||
$handlerException = null;
|
||||
|
||||
if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) {
|
||||
$e = array(
|
||||
@ -599,18 +600,20 @@ class ErrorHandler
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($this->exceptionHandler)) {
|
||||
throw $exception; // Give back $exception to the native handler
|
||||
}
|
||||
try {
|
||||
call_user_func($this->exceptionHandler, $exception);
|
||||
if (null !== $this->exceptionHandler) {
|
||||
return \call_user_func($this->exceptionHandler, $exception);
|
||||
}
|
||||
$handlerException = $handlerException ?: $exception;
|
||||
} catch (\Exception $handlerException) {
|
||||
} catch (\Throwable $handlerException) {
|
||||
}
|
||||
if (isset($handlerException)) {
|
||||
$this->exceptionHandler = null;
|
||||
$this->handleException($handlerException);
|
||||
$this->exceptionHandler = null;
|
||||
if ($exception === $handlerException) {
|
||||
self::$reservedMemory = null; // Disable the fatal error handler
|
||||
throw $exception; // Give back $exception to the native handler
|
||||
}
|
||||
$this->handleException($handlerException);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -626,15 +629,30 @@ class ErrorHandler
|
||||
return;
|
||||
}
|
||||
|
||||
self::$reservedMemory = null;
|
||||
$handler = self::$reservedMemory = null;
|
||||
$handlers = array();
|
||||
|
||||
$handler = set_error_handler('var_dump');
|
||||
$handler = is_array($handler) ? $handler[0] : null;
|
||||
restore_error_handler();
|
||||
while (!is_array($handler) || !$handler[0] instanceof self) {
|
||||
$handler = set_exception_handler('var_dump');
|
||||
restore_exception_handler();
|
||||
|
||||
if (!$handler instanceof self) {
|
||||
if (!$handler) {
|
||||
break;
|
||||
}
|
||||
restore_exception_handler();
|
||||
array_unshift($handlers, $handler);
|
||||
}
|
||||
foreach ($handlers as $h) {
|
||||
set_exception_handler($h);
|
||||
}
|
||||
if (!$handler) {
|
||||
return;
|
||||
}
|
||||
if ($handler !== $h) {
|
||||
$handler[0]->setExceptionHandler($h);
|
||||
}
|
||||
$handler = $handler[0];
|
||||
$handlers = array();
|
||||
|
||||
if ($exit = null === $error) {
|
||||
$error = error_get_last();
|
||||
|
@ -0,0 +1,36 @@
|
||||
--TEST--
|
||||
Test rethrowing in custom exception handler
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Debug;
|
||||
|
||||
$vendor = __DIR__;
|
||||
while (!file_exists($vendor.'/vendor')) {
|
||||
$vendor = dirname($vendor);
|
||||
}
|
||||
require $vendor.'/vendor/autoload.php';
|
||||
|
||||
if (true) {
|
||||
class TestLogger extends \Psr\Log\AbstractLogger
|
||||
{
|
||||
public function log($level, $message, array $context = array())
|
||||
{
|
||||
echo $message, "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_exception_handler(function ($e) { echo 123; throw $e; });
|
||||
ErrorHandler::register()->setDefaultLogger(new TestLogger());
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
throw new \Exception('foo');
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Uncaught Exception: foo
|
||||
123
|
||||
Fatal error: Uncaught %s:25
|
||||
Stack trace:
|
||||
%a
|
@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
Test catching fatal errors when handlers are nested
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Debug;
|
||||
|
||||
$vendor = __DIR__;
|
||||
while (!file_exists($vendor.'/vendor')) {
|
||||
$vendor = dirname($vendor);
|
||||
}
|
||||
require $vendor.'/vendor/autoload.php';
|
||||
|
||||
Debug::enable();
|
||||
ini_set('display_errors', 0);
|
||||
|
||||
$eHandler = set_error_handler('var_dump');
|
||||
$xHandler = set_exception_handler('var_dump');
|
||||
|
||||
var_dump(array(
|
||||
$eHandler[0] === $xHandler[0] ? 'Error and exception handlers do match' : 'Error and exception handlers are different',
|
||||
));
|
||||
|
||||
$eHandler[0]->setExceptionHandler('print_r');
|
||||
|
||||
if (true) {
|
||||
class Broken implements \Serializable {};
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(37) "Error and exception handlers do match"
|
||||
}
|
||||
object(Symfony\Component\Debug\Exception\FatalErrorException)#4 (8) {
|
||||
["message":protected]=>
|
||||
string(199) "Error: Class Symfony\Component\Debug\Broken contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (Serializable::serialize, Serializable::unserialize)"
|
||||
%a
|
||||
}
|
@ -1977,6 +1977,25 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
|
||||
);
|
||||
}
|
||||
|
||||
public function testMoneyWithoutCurrency()
|
||||
{
|
||||
$form = $this->factory->createNamed('name', 'money', 1234.56, array(
|
||||
'currency' => false,
|
||||
));
|
||||
|
||||
$this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')),
|
||||
'/input
|
||||
[@id="my&id"]
|
||||
[@type="text"]
|
||||
[@name="name"]
|
||||
[@class="my&class form-control"]
|
||||
[@value="1234.56"]
|
||||
[not(preceding-sibling::*)]
|
||||
[not(following-sibling::*)]
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
public function testNumber()
|
||||
{
|
||||
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\NumberType', 1234.56);
|
||||
|
@ -53,7 +53,7 @@ class MoneyTypeTest extends BaseTypeTest
|
||||
$view = $this->factory->create(static::TESTED_TYPE, null, array('currency' => 'JPY'))
|
||||
->createView();
|
||||
|
||||
$this->assertTrue((bool) strstr($view->vars['money_pattern'], '¥'));
|
||||
$this->assertSame('¥ {{ widget }}', $view->vars['money_pattern']);
|
||||
}
|
||||
|
||||
// https://github.com/symfony/symfony/issues/5458
|
||||
@ -72,4 +72,12 @@ class MoneyTypeTest extends BaseTypeTest
|
||||
{
|
||||
parent::testSubmitNull($expected, $norm, '');
|
||||
}
|
||||
|
||||
public function testMoneyPatternWithoutCurrency()
|
||||
{
|
||||
$view = $this->factory->create(static::TESTED_TYPE, null, array('currency' => false))
|
||||
->createView();
|
||||
|
||||
$this->assertSame('{{ widget }}', $view->vars['money_pattern']);
|
||||
}
|
||||
}
|
||||
|
@ -123,6 +123,10 @@ class IpUtils
|
||||
if (false !== strpos($ip, '/')) {
|
||||
list($address, $netmask) = explode('/', $ip, 2);
|
||||
|
||||
if ('0' === $netmask) {
|
||||
return (bool) unpack('n*', @inet_pton($address));
|
||||
}
|
||||
|
||||
if ($netmask < 1 || $netmask > 128) {
|
||||
return self::$checkedIps[$cacheKey] = false;
|
||||
}
|
||||
|
@ -62,6 +62,8 @@ class IpUtilsTest extends TestCase
|
||||
array(false, '2a01:198:603:0:396e:4789:8e99:890f', '::1'),
|
||||
array(true, '0:0:0:0:0:0:0:1', '::1'),
|
||||
array(false, '0:0:603:0:396e:4789:8e99:0001', '::1'),
|
||||
array(true, '0:0:603:0:396e:4789:8e99:0001', '::/0'),
|
||||
array(true, '0:0:603:0:396e:4789:8e99:0001', '2a01:198:603:0::/0'),
|
||||
array(true, '2a01:198:603:0:396e:4789:8e99:890f', array('::1', '2a01:198:603:0::/65')),
|
||||
array(true, '2a01:198:603:0:396e:4789:8e99:890f', array('2a01:198:603:0::/65', '::1')),
|
||||
array(false, '2a01:198:603:0:396e:4789:8e99:890f', array('::1', '1a01:198:603:0::/65')),
|
||||
|
@ -36,6 +36,7 @@ class DebugHandlersListener implements EventSubscriberInterface
|
||||
private $scream;
|
||||
private $fileLinkFormat;
|
||||
private $firstCall = true;
|
||||
private $hasTerminatedWithException;
|
||||
|
||||
/**
|
||||
* @param callable|null $exceptionHandler A handler that will be called on Exception
|
||||
@ -60,14 +61,16 @@ class DebugHandlersListener implements EventSubscriberInterface
|
||||
*/
|
||||
public function configure(Event $event = null)
|
||||
{
|
||||
if (!$this->firstCall) {
|
||||
if (!$event instanceof KernelEvent ? !$this->firstCall : !$event->isMasterRequest()) {
|
||||
return;
|
||||
}
|
||||
$this->firstCall = false;
|
||||
$this->firstCall = $this->hasTerminatedWithException = false;
|
||||
|
||||
$handler = set_exception_handler('var_dump');
|
||||
$handler = is_array($handler) ? $handler[0] : null;
|
||||
restore_exception_handler();
|
||||
|
||||
if ($this->logger || null !== $this->throwAt) {
|
||||
$handler = set_error_handler('var_dump');
|
||||
$handler = is_array($handler) ? $handler[0] : null;
|
||||
restore_error_handler();
|
||||
if ($handler instanceof ErrorHandler) {
|
||||
if ($this->logger) {
|
||||
$handler->setDefaultLogger($this->logger, $this->levels);
|
||||
@ -91,8 +94,16 @@ class DebugHandlersListener implements EventSubscriberInterface
|
||||
}
|
||||
if (!$this->exceptionHandler) {
|
||||
if ($event instanceof KernelEvent) {
|
||||
if (method_exists($event->getKernel(), 'terminateWithException')) {
|
||||
$this->exceptionHandler = array($event->getKernel(), 'terminateWithException');
|
||||
if (method_exists($kernel = $event->getKernel(), 'terminateWithException')) {
|
||||
$request = $event->getRequest();
|
||||
$hasRun = &$this->hasTerminatedWithException;
|
||||
$this->exceptionHandler = function (\Exception $e) use ($kernel, $request, &$hasRun) {
|
||||
if ($hasRun) {
|
||||
throw $e;
|
||||
}
|
||||
$hasRun = true;
|
||||
$kernel->terminateWithException($e, $request);
|
||||
};
|
||||
}
|
||||
} elseif ($event instanceof ConsoleEvent && $app = $event->getCommand()->getApplication()) {
|
||||
$output = $event->getOutput();
|
||||
@ -105,9 +116,6 @@ class DebugHandlersListener implements EventSubscriberInterface
|
||||
}
|
||||
}
|
||||
if ($this->exceptionHandler) {
|
||||
$handler = set_exception_handler('var_dump');
|
||||
$handler = is_array($handler) ? $handler[0] : null;
|
||||
restore_exception_handler();
|
||||
if ($handler instanceof ErrorHandler) {
|
||||
$h = $handler->setExceptionHandler('var_dump') ?: $this->exceptionHandler;
|
||||
$handler->setExceptionHandler($h);
|
||||
|
@ -78,14 +78,12 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \LogicException If the request stack is empty
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function terminateWithException(\Exception $exception)
|
||||
public function terminateWithException(\Exception $exception, Request $request = null)
|
||||
{
|
||||
if (!$request = $this->requestStack->getMasterRequest()) {
|
||||
throw new \LogicException('Request stack is empty', 0, $exception);
|
||||
if (!$request = $request ?: $this->requestStack->getMasterRequest()) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
$response = $this->handleException($exception, $request, self::MASTER_REQUEST);
|
||||
|
Reference in New Issue
Block a user