diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php index 807321352f..7f4f3d31ee 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php @@ -269,27 +269,21 @@ class JsonDescriptor extends Descriptor { $data = array(); - $registeredListeners = $eventDispatcher->getListeners($event, true); + $registeredListeners = $eventDispatcher->getListeners($event); if (null !== $event) { - krsort($registeredListeners); - foreach ($registeredListeners as $priority => $listeners) { - foreach ($listeners as $listener) { - $listener = $this->getCallableData($listener); - $listener['priority'] = $priority; - $data[] = $listener; - } + foreach ($registeredListeners as $listener) { + $l = $this->getCallableData($listener); + $l['priority'] = $eventDispatcher->getListenerPriority($event, $listener); + $data[] = $l; } } else { ksort($registeredListeners); foreach ($registeredListeners as $eventListened => $eventListeners) { - krsort($eventListeners); - foreach ($eventListeners as $priority => $listeners) { - foreach ($listeners as $listener) { - $listener = $this->getCallableData($listener); - $listener['priority'] = $priority; - $data[$eventListened][] = $listener; - } + foreach ($eventListeners as $eventListener) { + $l = $this->getCallableData($eventListener); + $l['priority'] = $eventDispatcher->getListenerPriority($eventListened, $eventListener); + $data[$eventListened][] = $l; } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php index d37146ee02..a24040bd3a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php @@ -253,30 +253,23 @@ class MarkdownDescriptor extends Descriptor $this->write(sprintf('# %s', $title)."\n"); - $registeredListeners = $eventDispatcher->getListeners($event, true); + $registeredListeners = $eventDispatcher->getListeners($event); if (null !== $event) { - krsort($registeredListeners); - $order = 1; - foreach ($registeredListeners as $priority => $listeners) { - foreach ($listeners as $listener) { - $this->write("\n".sprintf('## Listener %d', $order++)."\n"); - $this->describeCallable($listener); - $this->write(sprintf('- Priority: `%d`', $priority)."\n"); - } + foreach ($registeredListeners as $order => $listener) { + $this->write("\n".sprintf('## Listener %d', $order + 1)."\n"); + $this->describeCallable($listener); + $this->write(sprintf('- Priority: `%d`', $eventDispatcher->getListenerPriority($event, $listener))."\n"); } } else { ksort($registeredListeners); foreach ($registeredListeners as $eventListened => $eventListeners) { $this->write("\n".sprintf('## %s', $eventListened)."\n"); - krsort($eventListeners); - $order = 1; - foreach ($eventListeners as $priority => $listeners) { - foreach ($listeners as $listener) { - $this->write("\n".sprintf('### Listener %d', $order++)."\n"); - $this->describeCallable($listener); - $this->write(sprintf('- Priority: `%d`', $priority)."\n"); - } + + foreach ($eventListeners as $order => $eventListener) { + $this->write("\n".sprintf('### Listener %d', $order + 1)."\n"); + $this->describeCallable($eventListener); + $this->write(sprintf('- Priority: `%d`', $eventDispatcher->getListenerPriority($eventListened, $eventListener))."\n"); } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php index 1499fed821..c8a35584fa 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php @@ -341,15 +341,14 @@ class TextDescriptor extends Descriptor $options['output']->title($title); - $registeredListeners = $eventDispatcher->getListeners($event, true); - + $registeredListeners = $eventDispatcher->getListeners($event); if (null !== $event) { - $this->renderEventListenerTable($registeredListeners, $options['output']); + $this->renderEventListenerTable($eventDispatcher, $event, $registeredListeners, $options['output']); } else { ksort($registeredListeners); foreach ($registeredListeners as $eventListened => $eventListeners) { $options['output']->section(sprintf('"%s" event', $eventListened)); - $this->renderEventListenerTable($eventListeners, $options['output']); + $this->renderEventListenerTable($eventDispatcher, $eventListened, $eventListeners, $options['output']); } } } @@ -365,17 +364,14 @@ class TextDescriptor extends Descriptor /** * @param array $array */ - private function renderEventListenerTable(array $eventListeners, SymfonyStyle $renderer) + private function renderEventListenerTable(EventDispatcherInterface $eventDispatcher, $event, array $eventListeners, SymfonyStyle $renderer) { $tableHeaders = array('Order', 'Callable', 'Priority'); $tableRows = array(); - krsort($eventListeners); $order = 1; - foreach ($eventListeners as $priority => $listeners) { - foreach ($listeners as $listener) { - $tableRows[] = array(sprintf('#%d', $order++), $this->formatCallable($listener), $priority); - } + foreach ($eventListeners as $order => $listener) { + $tableRows[] = array(sprintf('#%d', $order + 1), $this->formatCallable($listener), $eventDispatcher->getListenerPriority($event, $listener)); } $renderer->table($tableHeaders, $tableRows); diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php index ca62972ec7..d7b8015487 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php @@ -429,9 +429,9 @@ class XmlDescriptor extends Descriptor $dom = new \DOMDocument('1.0', 'UTF-8'); $dom->appendChild($eventDispatcherXML = $dom->createElement('event-dispatcher')); - $registeredListeners = $eventDispatcher->getListeners($event, true); + $registeredListeners = $eventDispatcher->getListeners($event); if (null !== $event) { - $this->appendEventListenerDocument($eventDispatcherXML, $registeredListeners); + $this->appendEventListenerDocument($eventDispatcher, $event, $eventDispatcherXML, $registeredListeners); } else { ksort($registeredListeners); @@ -439,7 +439,7 @@ class XmlDescriptor extends Descriptor $eventDispatcherXML->appendChild($eventXML = $dom->createElement('event')); $eventXML->setAttribute('name', $eventListened); - $this->appendEventListenerDocument($eventXML, $eventListeners); + $this->appendEventListenerDocument($eventDispatcher, $eventListened, $eventXML, $eventListeners); } } @@ -450,16 +450,13 @@ class XmlDescriptor extends Descriptor * @param \DOMElement $element * @param array $eventListeners */ - private function appendEventListenerDocument(\DOMElement $element, array $eventListeners) + private function appendEventListenerDocument(EventDispatcherInterface $eventDispatcher, $event, \DOMElement $element, array $eventListeners) { - krsort($eventListeners); - foreach ($eventListeners as $priority => $listeners) { - foreach ($listeners as $listener) { - $callableXML = $this->getCallableDocument($listener); - $callableXML->childNodes->item(0)->setAttribute('priority', $priority); + foreach ($eventListeners as $listener) { + $callableXML = $this->getCallableDocument($listener); + $callableXML->childNodes->item(0)->setAttribute('priority', $eventDispatcher->getListenerPriority($event, $listener)); - $element->appendChild($element->ownerDocument->importNode($callableXML->childNodes->item(0), true)); - } + $element->appendChild($element->ownerDocument->importNode($callableXML->childNodes->item(0), true)); } } diff --git a/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php b/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php index a2a6ca8df1..5982b85f30 100644 --- a/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/ContainerAwareEventDispatcher.php @@ -117,7 +117,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher /** * {@inheritdoc} */ - public function getListeners($eventName = null, $withPriorities = false) + public function getListeners($eventName = null) { if (null === $eventName) { foreach ($this->listenerIds as $serviceEventName => $args) { @@ -127,7 +127,17 @@ class ContainerAwareEventDispatcher extends EventDispatcher $this->lazyLoad($eventName); } - return parent::getListeners($eventName, $withPriorities); + return parent::getListeners($eventName); + } + + /** + * {@inheritdoc} + */ + public function getListenerPriority($eventName, $listener) + { + $this->lazyLoad($eventName); + + return parent::getListenerPriority($eventName, $listener); } /** diff --git a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php index 5ff9ec72a0..35df8162b1 100644 --- a/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php @@ -94,9 +94,17 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface /** * {@inheritdoc} */ - public function getListeners($eventName = null, $withPriorities = false) + public function getListeners($eventName = null) { - return $this->dispatcher->getListeners($eventName, $withPriorities); + return $this->dispatcher->getListeners($eventName); + } + + /** + * {@inheritdoc} + */ + public function getListenerPriority($eventName, $listener) + { + return $this->dispatcher->getListenerPriority($eventName, $listener); } /** @@ -141,8 +149,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface $called = array(); foreach ($this->called as $eventName => $listeners) { foreach ($listeners as $listener) { - $priority = $this->getListenerPriority($eventName, $listener); - $info = $this->getListenerInfo($listener->getWrappedListener(), $eventName, $priority); + $info = $this->getListenerInfo($listener->getWrappedListener(), $eventName); $called[$eventName.'.'.$info['pretty']] = $info; } } @@ -156,7 +163,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface public function getNotCalledListeners() { try { - $allListeners = $this->getListeners(null, true); + $allListeners = $this->getListeners(); } catch (\Exception $e) { if (null !== $this->logger) { $this->logger->info('An exception was thrown while getting the uncalled listeners.', array('exception' => $e)); @@ -167,24 +174,22 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface } $notCalled = array(); - foreach ($allListeners as $eventName => $priorities) { - foreach ($priorities as $priority => $listeners) { - foreach ($listeners as $listener) { - $called = false; - if (isset($this->called[$eventName])) { - foreach ($this->called[$eventName] as $l) { - if ($l->getWrappedListener() === $listener) { - $called = true; + foreach ($allListeners as $eventName => $listeners) { + foreach ($listeners as $listener) { + $called = false; + if (isset($this->called[$eventName])) { + foreach ($this->called[$eventName] as $l) { + if ($l->getWrappedListener() === $listener) { + $called = true; - break; - } + break; } } + } - if (!$called) { - $info = $this->getListenerInfo($listener, $eventName, $priority); - $notCalled[$eventName.'.'.$info['pretty']] = $info; - } + if (!$called) { + $info = $this->getListenerInfo($listener, $eventName); + $notCalled[$eventName.'.'.$info['pretty']] = $info; } } } @@ -286,11 +291,11 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface * * @return array Information about the listener */ - private function getListenerInfo($listener, $eventName, $priority = null) + private function getListenerInfo($listener, $eventName) { $info = array( 'event' => $eventName, - 'priority' => $priority, + 'priority' => $this->getListenerPriority($eventName, $listener), ); if ($listener instanceof \Closure) { $info += array( @@ -339,28 +344,6 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface return $info; } - private function getListenerPriority($eventName, $listenerConfig) - { - try { - $allListeners = $this->getListeners(null, true); - } catch (\Exception $e) { - if (null !== $this->logger) { - $this->logger->info('An exception was thrown while getting the listeners.', array('exception' => $e)); - } - - return; - } - - $listenerWrapper = $listenerConfig->getWrappedListener(); - foreach ($allListeners[$eventName] as $priority => $listeners) { - foreach ($listeners as $listener) { - if (is_array($listenerWrapper) && $listenerWrapper[0] === $listener[0]) { - return $priority; - } - } - } - } - private function sortListenersByPriority($a, $b) { if (is_int($a['priority']) && !is_int($b['priority'])) { diff --git a/src/Symfony/Component/EventDispatcher/EventDispatcher.php b/src/Symfony/Component/EventDispatcher/EventDispatcher.php index 0728a7a467..2a033700ff 100644 --- a/src/Symfony/Component/EventDispatcher/EventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/EventDispatcher.php @@ -49,16 +49,8 @@ class EventDispatcher implements EventDispatcherInterface /** * {@inheritdoc} */ - public function getListeners($eventName = null, $withPriorities = false) + public function getListeners($eventName = null) { - if (true === $withPriorities) { - if (null !== $eventName) { - return isset($this->listeners[$eventName]) ? $this->listeners[$eventName] : array(); - } - - return array_filter($this->listeners); - } - if (null !== $eventName) { if (!isset($this->listeners[$eventName])) { return array(); @@ -80,6 +72,29 @@ class EventDispatcher implements EventDispatcherInterface return array_filter($this->sorted); } + /** + * Gets the listener priority for a specific event. + * + * Returns null if the event or the listener does not exist. + * + * @param string $eventName The name of the event + * @param callable $listener The listener to remove + * + * @return int|null The event listener priority + */ + public function getListenerPriority($eventName, $listener) + { + if (!isset($this->listeners[$eventName])) { + return; + } + + foreach ($this->listeners[$eventName] as $priority => $listeners) { + if (false !== ($key = array_search($listener, $listeners, true))) { + return $priority; + } + } + } + /** * {@inheritdoc} */ @@ -174,8 +189,6 @@ class EventDispatcher implements EventDispatcherInterface */ private function sortListeners($eventName) { - $this->sorted[$eventName] = array(); - krsort($this->listeners[$eventName]); $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]); } diff --git a/src/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php b/src/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php index f979304e9c..13e8572ed6 100644 --- a/src/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php +++ b/src/Symfony/Component/EventDispatcher/ImmutableEventDispatcher.php @@ -78,9 +78,17 @@ class ImmutableEventDispatcher implements EventDispatcherInterface /** * {@inheritdoc} */ - public function getListeners($eventName = null, $withPriorities = false) + public function getListeners($eventName = null) { - return $this->dispatcher->getListeners($eventName, $withPriorities); + return $this->dispatcher->getListeners($eventName); + } + + /** + * {@inheritdoc} + */ + public function getListenerPriority($eventName, $listener) + { + return $this->dispatcher->getListenerPriority($eventName, $listener); } /** diff --git a/src/Symfony/Component/EventDispatcher/Tests/AbstractEventDispatcherTest.php b/src/Symfony/Component/EventDispatcher/Tests/AbstractEventDispatcherTest.php index ad07fa13a1..30429d3f70 100644 --- a/src/Symfony/Component/EventDispatcher/Tests/AbstractEventDispatcherTest.php +++ b/src/Symfony/Component/EventDispatcher/Tests/AbstractEventDispatcherTest.php @@ -108,6 +108,20 @@ abstract class AbstractEventDispatcherTest extends \PHPUnit_Framework_TestCase $this->assertSame($expected, $this->dispatcher->getListeners()); } + public function testGetListenerPriority() + { + $listener1 = new TestEventListener(); + $listener2 = new TestEventListener(); + + $this->dispatcher->addListener('pre.foo', $listener1, -10); + $this->dispatcher->addListener('pre.foo', $listener2); + + $this->assertSame(-10, $this->dispatcher->getListenerPriority('pre.foo', $listener1)); + $this->assertSame(0, $this->dispatcher->getListenerPriority('pre.foo', $listener2)); + $this->assertNull($this->dispatcher->getListenerPriority('pre.bar', $listener2)); + $this->assertNull($this->dispatcher->getListenerPriority('pre.foo', function () {})); + } + public function testDispatch() { $this->dispatcher->addListener('pre.foo', array($this->listener, 'preFoo')); diff --git a/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php b/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php index cd72dd3c3b..1d4a8c8506 100644 --- a/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php +++ b/src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php @@ -25,7 +25,7 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase $dispatcher = new EventDispatcher(); $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); - $tdispatcher->addListener('foo', $listener = function () {; }); + $tdispatcher->addListener('foo', $listener = function () {}); $listeners = $dispatcher->getListeners('foo'); $this->assertCount(1, $listeners); $this->assertSame($listener, $listeners[0]); @@ -39,7 +39,7 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase $dispatcher = new EventDispatcher(); $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); - $tdispatcher->addListener('foo', $listener = function () {; }); + $tdispatcher->addListener('foo', $listener = function () {}); $this->assertSame($dispatcher->getListeners('foo'), $tdispatcher->getListeners('foo')); } @@ -51,7 +51,7 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase $this->assertFalse($dispatcher->hasListeners('foo')); $this->assertFalse($tdispatcher->hasListeners('foo')); - $tdispatcher->addListener('foo', $listener = function () {; }); + $tdispatcher->addListener('foo', $listener = function () {}); $this->assertTrue($dispatcher->hasListeners('foo')); $this->assertTrue($tdispatcher->hasListeners('foo')); } @@ -76,7 +76,7 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase { $dispatcher = new EventDispatcher(); $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch()); - $tdispatcher->addListener('foo', $listener = function () {; }); + $tdispatcher->addListener('foo', $listener = function () {}); $this->assertEquals(array(), $tdispatcher->getCalledListeners()); $this->assertEquals(array('foo.closure' => array('event' => 'foo', 'type' => 'Closure', 'pretty' => 'closure', 'priority' => 0)), $tdispatcher->getNotCalledListeners()); @@ -107,8 +107,8 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase $dispatcher = new EventDispatcher(); $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger); - $tdispatcher->addListener('foo', $listener1 = function () {; }); - $tdispatcher->addListener('foo', $listener2 = function () {; }); + $tdispatcher->addListener('foo', $listener1 = function () {}); + $tdispatcher->addListener('foo', $listener2 = function () {}); $logger->expects($this->at(0))->method('debug')->with('Notified event "foo" to listener "closure".'); $logger->expects($this->at(1))->method('debug')->with('Notified event "foo" to listener "closure".'); @@ -123,7 +123,7 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase $dispatcher = new EventDispatcher(); $tdispatcher = new TraceableEventDispatcher($dispatcher, new Stopwatch(), $logger); $tdispatcher->addListener('foo', $listener1 = function (Event $event) { $event->stopPropagation(); }); - $tdispatcher->addListener('foo', $listener2 = function () {; }); + $tdispatcher->addListener('foo', $listener2 = function () {}); $logger->expects($this->at(0))->method('debug')->with('Notified event "foo" to listener "closure".'); $logger->expects($this->at(1))->method('debug')->with('Listener "closure" stopped propagation of the event "foo".'); diff --git a/src/Symfony/Component/Yaml/CHANGELOG.md b/src/Symfony/Component/Yaml/CHANGELOG.md index 096cf654d8..da735a1d8e 100644 --- a/src/Symfony/Component/Yaml/CHANGELOG.md +++ b/src/Symfony/Component/Yaml/CHANGELOG.md @@ -1,6 +1,12 @@ CHANGELOG ========= +2.8.0 +----- + + * Deprecated non-escaped \ in double-quoted strings when parsing Yaml + ("Foo\Var" is not valid whereas "Foo\\Var" is) + 2.1.0 ----- diff --git a/src/Symfony/Component/Yaml/Tests/Fixtures/escapedCharacters.yml b/src/Symfony/Component/Yaml/Tests/Fixtures/escapedCharacters.yml index 09bf86e790..6ca044c8da 100644 --- a/src/Symfony/Component/Yaml/Tests/Fixtures/escapedCharacters.yml +++ b/src/Symfony/Component/Yaml/Tests/Fixtures/escapedCharacters.yml @@ -145,3 +145,11 @@ php: | array( 'double' => "some value\n \"some quoted string\" and 'some single quotes one'" ) +--- +test: Backslashes +yaml: | + { single: 'foo\Var', no-quotes: foo\Var, double: "foo\\Var" } +php: | + array( + 'single' => 'foo\Var', 'no-quotes' => 'foo\Var', 'double' => 'foo\Var' + ) diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index c5674a236d..008f2f364c 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -70,6 +70,23 @@ class InlineTest extends \PHPUnit_Framework_TestCase $this->assertSame($value, Inline::parse(Inline::dump($value))); } + /** + * @group legacy + * throws \Symfony\Component\Yaml\Exception\ParseException in 3.0 + */ + public function testParseScalarWithNonEscapedBlackslashShouldThrowException() + { + $this->assertSame('Foo\Var', Inline::parse('"Foo\Var"')); + } + + /** + * @expectedException \Symfony\Component\Yaml\Exception\ParseException + */ + public function testParseScalarWithNonEscapedBlackslashAtTheEndShouldThrowException() + { + Inline::parse('"Foo\\"'); + } + /** * @expectedException \Symfony\Component\Yaml\Exception\ParseException */ diff --git a/src/Symfony/Component/Yaml/Unescaper.php b/src/Symfony/Component/Yaml/Unescaper.php index 927ee9ddc0..313dcf39a8 100644 --- a/src/Symfony/Component/Yaml/Unescaper.php +++ b/src/Symfony/Component/Yaml/Unescaper.php @@ -22,7 +22,7 @@ class Unescaper /** * Regex fragment that matches an escaped character in a double quoted string. */ - const REGEX_ESCAPED_CHARACTER = "\\\\([0abt\tnvfre \\\"\\/\\\\N_LP]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})"; + const REGEX_ESCAPED_CHARACTER = "\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)"; /** * Unescapes a single quoted string. @@ -59,10 +59,13 @@ class Unescaper * @param string $value An escaped character * * @return string The unescaped character + * + * @internal This method is public to be usable as callback. It should not + * be used in user code. Should be changed in 3.0. */ public function unescapeCharacter($value) { - switch ($value{1}) { + switch ($value[1]) { case '0': return "\x0"; case 'a': @@ -109,6 +112,10 @@ class Unescaper return self::utf8chr(hexdec(substr($value, 2, 4))); case 'U': return self::utf8chr(hexdec(substr($value, 2, 8))); + default: + @trigger_error('Not escaping a backslash in a double-quoted string is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', E_USER_DEPRECATED); + + return $value; } }