Rely on iconv and symfony/polyfill-*

This commit is contained in:
Nicolas Grekas 2015-10-14 16:40:43 +02:00
parent aa2673b390
commit 303f05baaf
91 changed files with 158 additions and 766 deletions

View File

@ -21,7 +21,13 @@
"twig/twig": "~1.20|~2.0",
"psr/log": "~1.0",
"symfony/security-acl": "~2.7",
"paragonie/random_compat": "~1.0"
"symfony/polyfill-intl-icu": "~1.0",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php54": "~1.0",
"symfony/polyfill-php55": "~1.0",
"symfony/polyfill-php56": "~1.0",
"symfony/polyfill-php70": "~1.0",
"symfony/polyfill-util": "~1.0"
},
"replace": {
"symfony/asset": "self.version",
@ -77,7 +83,6 @@
"doctrine/orm": "~2.4,>=2.4.5",
"doctrine/doctrine-bundle": "~1.2",
"monolog/monolog": "~1.11",
"ircmaxell/password-compat": "~1.0",
"ocramius/proxy-manager": "~0.4|~1.0",
"egulias/email-validator": "~1.2",
"phpdocumentor/reflection": "^1.0.7"
@ -96,10 +101,8 @@
"Symfony\\Component\\": "src/Symfony/Component/"
},
"classmap": [
"src/Symfony/Component/HttpFoundation/Resources/stubs",
"src/Symfony/Component/Intl/Resources/stubs"
],
"files": [ "src/Symfony/Component/Intl/Resources/stubs/functions.php" ]
]
},
"minimum-stability": "dev",
"extra": {

View File

@ -99,16 +99,9 @@ class DbalLogger implements SQLLogger
}
// detect if the too long string must be shorten
if (function_exists('mb_strlen')) {
if (self::MAX_STRING_LENGTH < mb_strlen($params[$index], 'UTF-8')) {
$params[$index] = mb_substr($params[$index], 0, self::MAX_STRING_LENGTH - 6, 'UTF-8').' [...]';
continue;
}
} else {
if (self::MAX_STRING_LENGTH < strlen($params[$index])) {
$params[$index] = substr($params[$index], 0, self::MAX_STRING_LENGTH - 6).' [...]';
continue;
}
if (self::MAX_STRING_LENGTH < iconv_strlen($params[$index], 'UTF-8')) {
$params[$index] = iconv_substr($params[$index], 0, self::MAX_STRING_LENGTH - 6, 'UTF-8').' [...]';
continue;
}
}

View File

@ -132,9 +132,6 @@ class DbalLoggerTest extends \PHPUnit_Framework_TestCase
));
}
/**
* @requires extension mbstring
*/
public function testLogUTF8LongString()
{
$logger = $this->getMock('Psr\\Log\\LoggerInterface');
@ -160,7 +157,7 @@ class DbalLoggerTest extends \PHPUnit_Framework_TestCase
$dbalLogger
->expects($this->once())
->method('log')
->with('SQL', array('short' => $shortString, 'long' => mb_substr($longString, 0, DbalLogger::MAX_STRING_LENGTH - 6, mb_detect_encoding($longString)).' [...]'))
->with('SQL', array('short' => $shortString, 'long' => iconv_substr($longString, 0, DbalLogger::MAX_STRING_LENGTH - 6, 'UTF-8').' [...]'))
;
$dbalLogger->startQuery('SQL', array(

View File

@ -24,7 +24,6 @@ class SymfonyTestsListener extends \PHPUnit_Framework_BaseTestListener
private $skippedFile = false;
private $wasSkipped = array();
private $isSkipped = array();
private $testsStack = array();
public function __destruct()
{

View File

@ -24,7 +24,7 @@
"symfony/finder": "~2.3|~3.0.0",
"symfony/form": "~2.8",
"symfony/http-kernel": "~2.8|~3.0.0",
"symfony/intl": "~2.3|~3.0.0",
"symfony/polyfill-intl-icu": "~1.0",
"symfony/routing": "~2.2|~3.0.0",
"symfony/templating": "~2.1|~3.0.0",
"symfony/translation": "~2.7|~3.0.0",

View File

@ -240,7 +240,7 @@ EOF
{
$string = trim(preg_replace('/\s+/', ' ', $string));
if (function_exists('mb_strlen') && false !== $encoding = mb_detect_encoding($string)) {
if (false !== $encoding = mb_detect_encoding($string, null, true)) {
if (mb_strlen($string, $encoding) > $length) {
return mb_substr($string, 0, $length - 3, $encoding).'...';
}

View File

@ -24,6 +24,7 @@
"symfony/event-dispatcher": "~2.8|~3.0.0",
"symfony/http-foundation": "~2.4.9|~2.5,>=2.5.4|~3.0.0",
"symfony/http-kernel": "~2.8",
"symfony/polyfill-mbstring": "~1.0",
"symfony/filesystem": "~2.3|~3.0.0",
"symfony/routing": "~2.8|~3.0.0",
"symfony/security-core": "~2.6|~3.0.0",
@ -40,7 +41,7 @@
"symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
"symfony/dom-crawler": "~2.0,>=2.0.5|~3.0.0",
"symfony/finder": "~2.0,>=2.0.5|~3.0.0",
"symfony/intl": "~2.3|~3.0.0",
"symfony/polyfill-intl-icu": "~1.0",
"symfony/security": "~2.6|~3.0.0",
"symfony/form": "~2.8",
"symfony/expression-language": "~2.6|~3.0.0",

View File

@ -23,7 +23,6 @@
},
"require-dev": {
"symfony/browser-kit": "~2.4|~3.0.0",
"symfony/config": "~2.8|~3.0.0",
"symfony/console": "~2.7|~3.0.0",
"symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
"symfony/dom-crawler": "~2.0,>=2.0.5|~3.0.0",
@ -37,8 +36,7 @@
"symfony/yaml": "~2.0,>=2.0.5|~3.0.0",
"symfony/expression-language": "~2.6|~3.0.0",
"doctrine/doctrine-bundle": "~1.2",
"twig/twig": "~1.20|~2.0",
"ircmaxell/password-compat": "~1.0"
"twig/twig": "~1.20|~2.0"
},
"autoload": {
"psr-4": { "Symfony\\Bundle\\SecurityBundle\\": "" }

View File

@ -1077,11 +1077,7 @@ class Application
private function stringWidth($string)
{
if (!function_exists('mb_strwidth')) {
return strlen($string);
}
if (false === $encoding = mb_detect_encoding($string)) {
if (false === $encoding = mb_detect_encoding($string, null, true)) {
return strlen($string);
}
@ -1094,11 +1090,7 @@ class Application
// additionally, array_slice() is not enough as some character has doubled width.
// we need a function to split string not by character count but by string width
if (!function_exists('mb_strwidth')) {
return str_split($string, $width);
}
if (false === $encoding = mb_detect_encoding($string)) {
if (false === $encoding = mb_detect_encoding($string, null, true)) {
return str_split($string, $width);
}

View File

@ -51,11 +51,7 @@ abstract class Helper implements HelperInterface
*/
public static function strlen($string)
{
if (!function_exists('mb_strwidth')) {
return strlen($string);
}
if (false === $encoding = mb_detect_encoding($string)) {
if (false === $encoding = mb_detect_encoding($string, null, true)) {
return strlen($string);
}

View File

@ -351,7 +351,7 @@ class Table
}
// str_pad won't work properly with multi-byte strings, we need to fix the padding
if (function_exists('mb_strwidth') && false !== $encoding = mb_detect_encoding($cell)) {
if (false !== $encoding = mb_detect_encoding($cell, null, true)) {
$width += strlen($cell) - mb_strwidth($cell, $encoding);
}

View File

@ -558,9 +558,6 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
$this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception4.txt', $tester->getDisplay(true), '->renderException() wraps messages when they are bigger than the terminal');
}
/**
* @requires extension mbstring
*/
public function testRenderExceptionWithDoubleWidthCharacters()
{
$application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));

View File

@ -52,9 +52,6 @@ class FormatterHelperTest extends \PHPUnit_Framework_TestCase
);
}
/**
* @requires extension mbstring
*/
public function testFormatBlockWithDiacriticLetters()
{
$formatter = new FormatterHelper();
@ -68,9 +65,6 @@ class FormatterHelperTest extends \PHPUnit_Framework_TestCase
);
}
/**
* @requires extension mbstring
*/
public function testFormatBlockWithDoubleWidthDiacriticLetters()
{
$formatter = new FormatterHelper();

View File

@ -155,9 +155,6 @@ class LegacyProgressHelperTest extends \PHPUnit_Framework_TestCase
$progress->advance(1);
}
/**
* @requires extension mbstring
*/
public function testMultiByteSupport()
{
$progress = new ProgressHelper();

View File

@ -256,9 +256,6 @@ TABLE
);
}
/**
* @requires extension mbstring
*/
public function testRenderMultiByte()
{
$table = new TableHelper();
@ -282,9 +279,6 @@ TABLE;
$this->assertEquals($expected, $this->getOutputContent($output));
}
/**
* @requires extension mbstring
*/
public function testRenderFullWidthCharacters()
{
$table = new TableHelper();

View File

@ -307,9 +307,6 @@ class ProgressBarTest extends \PHPUnit_Framework_TestCase
$bar->advance(1);
}
/**
* @requires extension mbstring
*/
public function testMultiByteSupport()
{
$bar = new ProgressBar($output = $this->getOutputStream());
@ -541,9 +538,6 @@ class ProgressBarTest extends \PHPUnit_Framework_TestCase
);
}
/**
* @requires extension mbstring
*/
public function testAnsiColorsAndEmojis()
{
$bar = new ProgressBar($output = $this->getOutputStream(), 15);

View File

@ -464,9 +464,6 @@ TABLE
);
}
/**
* @requires extension mbstring
*/
public function testRenderMultiByte()
{
$table = new Table($output = $this->getOutputStream());

View File

@ -16,7 +16,8 @@
}
],
"require": {
"php": ">=5.3.9"
"php": ">=5.3.9",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
"symfony/event-dispatcher": "~2.1|~3.0.0",

View File

@ -173,34 +173,7 @@ class Crawler extends \SplObjectStorage
try {
// Convert charset to HTML-entities to work around bugs in DOMDocument::loadHTML()
if (function_exists('mb_convert_encoding')) {
$content = mb_convert_encoding($content, 'HTML-ENTITIES', $charset);
} elseif (function_exists('iconv')) {
$content = preg_replace_callback(
'/[\x80-\xFF]+/',
function ($m) {
$m = unpack('C*', $m[0]);
$i = 1;
$entities = '';
while (isset($m[$i])) {
if (0xF0 <= $m[$i]) {
$c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
} elseif (0xE0 <= $m[$i]) {
$c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
} else {
$c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
}
$entities .= '&#'.$c.';';
}
return $entities;
},
iconv($charset, 'UTF-8', $content)
);
}
$content = mb_convert_encoding($content, 'HTML-ENTITIES', $charset);
} catch (\Exception $e) {
}

View File

@ -102,7 +102,6 @@ class CrawlerTest extends \PHPUnit_Framework_TestCase
/**
* @covers Symfony\Component\DomCrawler\Crawler::addHtmlContent
* @requires extension mbstring
*/
public function testAddHtmlContentCharset()
{
@ -137,7 +136,6 @@ class CrawlerTest extends \PHPUnit_Framework_TestCase
/**
* @covers Symfony\Component\DomCrawler\Crawler::addHtmlContent
* @requires extension mbstring
*/
public function testAddHtmlContentCharsetGbk()
{

View File

@ -16,7 +16,8 @@
}
],
"require": {
"php": ">=5.3.9"
"php": ">=5.3.9",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
"symfony/css-selector": "~2.8|~3.0.0"

View File

@ -197,7 +197,7 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
throw new TransformationFailedException('I don\'t have a clear idea what infinity looks like');
}
if (function_exists('mb_detect_encoding') && false !== $encoding = mb_detect_encoding($value)) {
if (false !== $encoding = mb_detect_encoding($value, null, true)) {
$length = mb_strlen($value, $encoding);
$remainder = mb_substr($value, $position, $length, $encoding);
} else {

View File

@ -238,8 +238,6 @@ class NumberToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase
/**
* @see https://github.com/symfony/symfony/issues/7609
*
* @requires extension mbstring
*/
public function testReverseTransformWithGroupingAndFixedSpaces()
{
@ -583,7 +581,6 @@ class NumberToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
* @expectedExceptionMessage The number contains unrecognized characters: "foo8"
* @requires extension mbstring
*/
public function testReverseTransformDisallowsCenteredExtraCharactersMultibyte()
{
@ -600,7 +597,6 @@ class NumberToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
* @expectedExceptionMessage The number contains unrecognized characters: "foo8"
* @requires extension mbstring
*/
public function testReverseTransformIgnoresTrailingSpacesInExceptionMessage()
{
@ -628,7 +624,6 @@ class NumberToLocalizedStringTransformerTest extends \PHPUnit_Framework_TestCase
/**
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
* @expectedExceptionMessage The number contains unrecognized characters: "foo"
* @requires extension mbstring
*/
public function testReverseTransformDisallowsTrailingExtraCharactersMultibyte()
{

View File

@ -24,7 +24,6 @@ class StringUtilTest extends \PHPUnit_Framework_TestCase
/**
* @dataProvider spaceProvider
* @requires extension mbstring
*/
public function testTrimUtf8Separators($hex)
{

View File

@ -20,6 +20,7 @@
"symfony/event-dispatcher": "~2.1|~3.0.0",
"symfony/intl": "~2.4|~3.0.0",
"symfony/options-resolver": "~2.6",
"symfony/polyfill-mbstring": "~1.0",
"symfony/property-access": "~2.3|~3.0.0"
},
"require-dev": {

View File

@ -142,7 +142,7 @@ class JsonResponse extends Response
}
if (JSON_ERROR_NONE !== json_last_error()) {
throw new \InvalidArgumentException($this->transformJsonError());
throw new \InvalidArgumentException(json_last_error_msg());
}
$this->data = $data;
@ -196,31 +196,4 @@ class JsonResponse extends Response
return $this->setContent($this->data);
}
private function transformJsonError()
{
if (function_exists('json_last_error_msg')) {
return json_last_error_msg();
}
switch (json_last_error()) {
case JSON_ERROR_DEPTH:
return 'Maximum stack depth exceeded.';
case JSON_ERROR_STATE_MISMATCH:
return 'Underflow or the modes mismatch.';
case JSON_ERROR_CTRL_CHAR:
return 'Unexpected control character found.';
case JSON_ERROR_SYNTAX:
return 'Syntax error, malformed JSON.';
case JSON_ERROR_UTF8:
return 'Malformed UTF-8 characters, possibly incorrectly encoded.';
default:
return 'Unknown error.';
}
}
}

View File

@ -34,18 +34,6 @@ $response->send();
The Request and the Response classes have many other methods that implement
the HTTP specification.
Loading
-------
If you are not using Composer but are using PHP 5.3.x, you must add the following to your autoloader:
```php
// SessionHandlerInterface
if (!interface_exists('SessionHandlerInterface')) {
$loader->registerPrefixFallback(__DIR__.'/../vendor/symfony/src/Symfony/Component/HttpFoundation/Resources/stubs');
}
```
Resources
---------

View File

@ -1,102 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* SessionHandlerInterface for PHP < 5.4.
*
* The order in which these methods are invoked by PHP are:
* 1. open [session_start]
* 2. read
* 3. gc [optional depending on probability settings: gc_probability / gc_divisor]
* 4. destroy [optional when session_regenerate_id(true) is used]
* 5. write [session_write_close] or destroy [session_destroy]
* 6. close
*
* Extensive documentation can be found at php.net, see links:
*
* @see http://php.net/sessionhandlerinterface
* @see http://php.net/session.customhandler
* @see http://php.net/session-set-save-handler
*
* @author Drak <drak@zikula.org>
* @author Tobias Schultze <http://tobion.de>
*/
interface SessionHandlerInterface
{
/**
* Re-initializes existing session, or creates a new one.
*
* @see http://php.net/sessionhandlerinterface.open
*
* @param string $savePath Save path
* @param string $sessionName Session name, see http://php.net/function.session-name.php
*
* @return bool true on success, false on failure
*/
public function open($savePath, $sessionName);
/**
* Closes the current session.
*
* @see http://php.net/sessionhandlerinterface.close
*
* @return bool true on success, false on failure
*/
public function close();
/**
* Reads the session data.
*
* @see http://php.net/sessionhandlerinterface.read
*
* @param string $sessionId Session ID, see http://php.net/function.session-id
*
* @return string Same session data as passed in write() or empty string when non-existent or on failure
*/
public function read($sessionId);
/**
* Writes the session data to the storage.
*
* Care, the session ID passed to write() can be different from the one previously
* received in read() when the session ID changed due to session_regenerate_id().
*
* @see http://php.net/sessionhandlerinterface.write
*
* @param string $sessionId Session ID , see http://php.net/function.session-id
* @param string $data Serialized session data to save
*
* @return bool true on success, false on failure
*/
public function write($sessionId, $data);
/**
* Destroys a session.
*
* @see http://php.net/sessionhandlerinterface.destroy
*
* @param string $sessionId Session ID, see http://php.net/function.session-id
*
* @return bool true on success, false on failure
*/
public function destroy($sessionId);
/**
* Cleans up expired sessions (garbage collection).
*
* @see http://php.net/sessionhandlerinterface.gc
*
* @param string|int $maxlifetime Sessions that have not updated for the last maxlifetime seconds will be removed
*
* @return bool true on success, false on failure
*/
public function gc($maxlifetime);
}

View File

@ -101,11 +101,7 @@ class NativeSessionStorage implements SessionStorageInterface
session_cache_limiter(''); // disable by default because it's managed by HeaderBag (if used)
ini_set('session.use_cookies', 1);
if (PHP_VERSION_ID >= 50400) {
session_register_shutdown();
} else {
register_shutdown_function('session_write_close');
}
session_register_shutdown();
$this->setMetadataBag($metaBag);
$this->setOptions($options);

View File

@ -16,14 +16,14 @@
}
],
"require": {
"php": ">=5.3.9"
"php": ">=5.3.9",
"symfony/polyfill-php54": "~1.0"
},
"require-dev": {
"symfony/expression-language": "~2.4|~3.0.0"
},
"autoload": {
"psr-4": { "Symfony\\Component\\HttpFoundation\\": "" },
"classmap": [ "Resources/stubs" ]
"psr-4": { "Symfony\\Component\\HttpFoundation\\": "" }
},
"minimum-stability": "dev",
"extra": {

View File

@ -105,7 +105,7 @@ class MongoDbProfilerStorageTest extends AbstractProfilerStorageTest
$profile = new Profile('utf8_test_profile');
$data = 'HЁʃʃϿ, ϢorЃd!';
$nonUtf8Data = mb_convert_encoding($data, 'UCS-2');
$nonUtf8Data = iconv('UTF-8', 'UCS-2', $data);
$collector = new MongoDbProfilerStorageTestDataCollector();
$collector->setData($nonUtf8Data);

View File

@ -30,6 +30,8 @@ use Symfony\Component\Intl\Locale\Locale;
*
* @author Igor Wiedler <igor@wiedler.ch>
* @author Bernhard Schussek <bschussek@gmail.com>
*
* @internal
*/
class Collator
{

View File

@ -53,37 +53,10 @@ class JsonBundleReader implements BundleReaderInterface
'The resource bundle "%s/%s.json" contains invalid JSON: %s',
$path,
$locale,
self::getLastJsonError()
json_last_error_msg()
));
}
return $data;
}
/**
* @return string The last error message created by {@link json_decode()}
*
* @link http://de2.php.net/manual/en/function.json-last-error-msg.php#113243
*/
private static function getLastJsonError()
{
if (function_exists('json_last_error_msg')) {
return json_last_error_msg();
}
static $errors = array(
JSON_ERROR_NONE => null,
JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch',
JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON',
JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded',
);
$error = json_last_error();
return array_key_exists($error, $errors)
? $errors[$error]
: sprintf('Unknown error (%s)', $error);
}
}

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for AM/PM markers format.
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class AmPmTransformer extends Transformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for day of week format.
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class DayOfWeekTransformer extends Transformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for day of year format.
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class DayOfYearTransformer extends Transformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for day format.
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class DayTransformer extends Transformer
{

View File

@ -18,6 +18,8 @@ use Symfony\Component\Intl\Globals\IntlGlobals;
* Parser and formatter for date formats.
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class FullTransformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for 12 hour format (0-11).
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class Hour1200Transformer extends HourTransformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for 12 hour format (1-12).
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class Hour1201Transformer extends HourTransformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for 24 hour format (0-23).
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class Hour2400Transformer extends HourTransformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for 24 hour format (1-24).
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class Hour2401Transformer extends HourTransformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Base class for hour transformers.
*
* @author Eriksen Costa <eriksen.costa@infranology.com.br>
*
* @internal
*/
abstract class HourTransformer extends Transformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for minute format.
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class MinuteTransformer extends Transformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for month format.
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class MonthTransformer extends Transformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for quarter format.
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class QuarterTransformer extends Transformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for the second format.
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class SecondTransformer extends Transformer
{

View File

@ -17,6 +17,8 @@ use Symfony\Component\Intl\Exception\NotImplementedException;
* Parser and formatter for time zone format.
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class TimeZoneTransformer extends Transformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for date formats.
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
abstract class Transformer
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\DateFormatter\DateFormat;
* Parser and formatter for year format.
*
* @author Igor Wiedler <igor@wiedler.ch>
*
* @internal
*/
class YearTransformer extends Transformer
{

View File

@ -43,6 +43,8 @@ use Symfony\Component\Intl\Locale\Locale;
*
* @author Igor Wiedler <igor@wiedler.ch>
* @author Bernhard Schussek <bschussek@gmail.com>
*
* @internal
*/
class IntlDateFormatter
{

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Intl\Globals;
* Provides fake static versions of the global functions in the intl extension.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*
* @internal
*/
abstract class IntlGlobals
{

View File

@ -21,6 +21,8 @@ use Symfony\Component\Intl\Exception\MethodNotImplementedException;
*
* @author Eriksen Costa <eriksen.costa@infranology.com.br>
* @author Bernhard Schussek <bschussek@gmail.com>
*
* @internal
*/
class Locale
{

View File

@ -37,6 +37,8 @@ use Symfony\Component\Intl\Locale\Locale;
*
* @author Eriksen Costa <eriksen.costa@infranology.com.br>
* @author Bernhard Schussek <bschussek@gmail.com>
*
* @internal
*/
class NumberFormatter
{

View File

@ -1,78 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Symfony\Component\Intl\Globals\IntlGlobals;
if (!function_exists('intl_is_failure')) {
/**
* Stub implementation for the {@link intl_is_failure()} function of the intl
* extension.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*
* @param int $errorCode The error code returned by intl_get_error_code().
*
* @return bool Whether the error code indicates an error.
*
* @see IntlGlobals::isFailure()
*/
function intl_is_failure($errorCode)
{
return IntlGlobals::isFailure($errorCode);
}
/**
* Stub implementation for the {@link intl_get_error_code()} function of the
* intl extension.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*
* @return bool The error code of the last intl function call or
* IntlGlobals::U_ZERO_ERROR if no error occurred.
*
* @see IntlGlobals::getErrorCode()
*/
function intl_get_error_code()
{
return IntlGlobals::getErrorCode();
}
/**
* Stub implementation for the {@link intl_get_error_code()} function of the
* intl extension.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*
* @return bool The error message of the last intl function call or
* "U_ZERO_ERROR" if no error occurred.
*
* @see IntlGlobals::getErrorMessage()
*/
function intl_get_error_message()
{
return IntlGlobals::getErrorMessage();
}
/**
* Stub implementation for the {@link intl_error_name()} function of the intl
* extension.
*
* @param int $errorCode The error code.
*
* @return string The name of the error code constant.
*
* @see IntlGlobals::getErrorName()
*/
function intl_error_name($errorCode)
{
return IntlGlobals::getErrorName($errorCode);
}
}

View File

@ -24,7 +24,9 @@
}
],
"require": {
"php": ">=5.3.9"
"php": ">=5.3.9",
"symfony/polyfill-intl-icu": "~1.0",
"symfony/polyfill-php54": "~1.0"
},
"require-dev": {
"symfony/filesystem": "~2.1|~3.0.0"
@ -34,8 +36,7 @@
},
"autoload": {
"psr-4": { "Symfony\\Component\\Intl\\": "" },
"classmap": [ "Resources/stubs" ],
"files": [ "Resources/stubs/functions.php" ]
"classmap": [ "Resources/stubs" ]
},
"minimum-stability": "dev",
"extra": {

View File

@ -97,11 +97,7 @@ class LdapClient implements LdapClientInterface
*/
public function escape($subject, $ignore = '', $flags = 0)
{
if (function_exists('ldap_escape')) {
return ldap_escape($subject, $ignore, $flags);
}
return $this->doEscape($subject, $ignore, $flags);
return ldap_escape($subject, $ignore, $flags);
}
private function connect()
@ -132,98 +128,4 @@ class LdapClient implements LdapClientInterface
$this->connection = null;
}
/**
* Stub implementation of the {@link ldap_escape()} function of the ldap
* extension.
*
* Escape strings for safe use in LDAP filters and DNs.
*
* @author Chris Wright <ldapi@daverandom.com>
*
* @param string $subject
* @param string $ignore
* @param int $flags
*
* @return string
*
* @see http://stackoverflow.com/a/8561604
*/
private function doEscape($subject, $ignore = '', $flags = 0)
{
$charMaps = $this->getCharmaps();
// Create the base char map to escape
$flags = (int) $flags;
$charMap = array();
if ($flags & self::LDAP_ESCAPE_FILTER) {
$charMap += $charMaps[self::LDAP_ESCAPE_FILTER];
}
if ($flags & self::LDAP_ESCAPE_DN) {
$charMap += $charMaps[self::LDAP_ESCAPE_DN];
}
if (!$charMap) {
$charMap = $charMaps[0];
}
// Remove any chars to ignore from the list
$ignore = (string) $ignore;
for ($i = 0, $l = strlen($ignore); $i < $l; ++$i) {
unset($charMap[$ignore[$i]]);
}
// Do the main replacement
$result = strtr($subject, $charMap);
// Encode leading/trailing spaces if LDAP_ESCAPE_DN is passed
if ($flags & self::LDAP_ESCAPE_DN) {
if ($result[0] === ' ') {
$result = '\\20'.substr($result, 1);
}
if ($result[strlen($result) - 1] === ' ') {
$result = substr($result, 0, -1).'\\20';
}
}
return $result;
}
private function getCharmaps()
{
if (null !== $this->charmaps) {
return $this->charmaps;
}
$charMaps = array(
self::LDAP_ESCAPE_FILTER => array('\\', '*', '(', ')', "\x00"),
self::LDAP_ESCAPE_DN => array('\\', ',', '=', '+', '<', '>', ';', '"', '#'),
);
$charMaps[0] = array();
for ($i = 0; $i < 256; ++$i) {
$charMaps[0][chr($i)] = sprintf('\\%02x', $i);
}
for ($i = 0, $l = count($charMaps[self::LDAP_ESCAPE_FILTER]); $i < $l; ++$i) {
$chr = $charMaps[self::LDAP_ESCAPE_FILTER][$i];
unset($charMaps[self::LDAP_ESCAPE_FILTER][$i]);
$charMaps[self::LDAP_ESCAPE_FILTER][$chr] = $charMaps[0][$chr];
}
for ($i = 0, $l = count($charMaps[self::LDAP_ESCAPE_DN]); $i < $l; ++$i) {
$chr = $charMaps[self::LDAP_ESCAPE_DN][$i];
unset($charMaps[self::LDAP_ESCAPE_DN][$i]);
$charMaps[self::LDAP_ESCAPE_DN][$chr] = $charMaps[0][$chr];
}
$this->charmaps = $charMaps;
return $this->charmaps;
}
}

View File

@ -1,52 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;
use Symfony\Component\Ldap\LdapClient;
/**
* @requires extension ldap
*/
class LdapClientTest extends \PHPUnit_Framework_TestCase
{
/**
* @dataProvider provideLdapEscapeValues
*/
public function testLdapEscape($subject, $ignore, $flags, $expected)
{
$ldap = new LdapClient();
$this->assertSame($expected, $ldap->escape($subject, $ignore, $flags));
}
/**
* Provides values for the ldap_escape shim. These tests come from the official
* extension.
*
* @see https://github.com/php/php-src/blob/master/ext/ldap/tests/ldap_escape_dn.phpt
* @see https://github.com/php/php-src/blob/master/ext/ldap/tests/ldap_escape_all.phpt
* @see https://github.com/php/php-src/blob/master/ext/ldap/tests/ldap_escape_both.phpt
* @see https://github.com/php/php-src/blob/master/ext/ldap/tests/ldap_escape_filter.phpt
* @see https://github.com/php/php-src/blob/master/ext/ldap/tests/ldap_escape_ignore.phpt
*
* @return array
*/
public function provideLdapEscapeValues()
{
return array(
array('foo=bar(baz)*', null, LdapClient::LDAP_ESCAPE_DN, 'foo\3dbar(baz)*'),
array('foo=bar(baz)*', null, null, '\66\6f\6f\3d\62\61\72\28\62\61\7a\29\2a'),
array('foo=bar(baz)*', null, LdapClient::LDAP_ESCAPE_DN | LdapClient::LDAP_ESCAPE_FILTER, 'foo\3dbar\28baz\29\2a'),
array('foo=bar(baz)*', null, LdapClient::LDAP_ESCAPE_FILTER, 'foo=bar\28baz\29\2a'),
array('foo=bar(baz)*', 'ao', null, '\66oo\3d\62a\72\28\62a\7a\29\2a'),
);
}
}

View File

@ -17,6 +17,7 @@
],
"require": {
"php": ">=5.3.9",
"symfony/polyfill-php56": "~1.0",
"ext-ldap": "*"
},
"autoload": {

View File

@ -34,10 +34,6 @@ class BCryptPasswordEncoder extends BasePasswordEncoder
*/
public function __construct($cost)
{
if (!function_exists('password_hash')) {
throw new \RuntimeException('To use the BCrypt encoder, you need to upgrade to PHP 5.5 or install the "ircmaxell/password-compat" via Composer.');
}
$cost = (int) $cost;
if ($cost < 4 || $cost > 31) {
throw new \InvalidArgumentException('Cost must be in the range of 4-31.');

View File

@ -11,8 +11,6 @@
namespace Symfony\Component\Security\Core\Encoder;
use Symfony\Component\Security\Core\Util\StringUtils;
/**
* BasePasswordEncoder is the base class for all password encoders.
*
@ -83,7 +81,7 @@ abstract class BasePasswordEncoder implements PasswordEncoderInterface
*/
protected function comparePasswords($password1, $password2)
{
return StringUtils::equals($password1, $password2);
return hash_equals($password1, $password2);
}
/**

View File

@ -64,11 +64,7 @@ class Pbkdf2PasswordEncoder extends BasePasswordEncoder
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
}
if (function_exists('hash_pbkdf2')) {
$digest = hash_pbkdf2($this->algorithm, $raw, $salt, $this->iterations, $this->length, true);
} else {
$digest = $this->hashPbkdf2($this->algorithm, $raw, $salt, $this->iterations, $this->length);
}
$digest = hash_pbkdf2($this->algorithm, $raw, $salt, $this->iterations, $this->length, true);
return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);
}
@ -80,24 +76,4 @@ class Pbkdf2PasswordEncoder extends BasePasswordEncoder
{
return !$this->isPasswordTooLong($raw) && $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
}
private function hashPbkdf2($algorithm, $password, $salt, $iterations, $length = 0)
{
// Number of blocks needed to create the derived key
$blocks = ceil($length / strlen(hash($algorithm, null, true)));
$digest = '';
for ($i = 1; $i <= $blocks; ++$i) {
$ib = $block = hash_hmac($algorithm, $salt.pack('N', $i), $password, true);
// Iterations
for ($j = 1; $j < $iterations; ++$j) {
$ib ^= ($block = hash_hmac($algorithm, $block, $password, true));
}
$digest .= $ib;
}
return substr($digest, 0, $this->length);
}
}

View File

@ -15,6 +15,8 @@ use Symfony\Component\Security\Core\Util\StringUtils;
/**
* Data from PHP.net's hash_equals tests.
*
* @group legacy
*/
class StringUtilsTest extends \PHPUnit_Framework_TestCase
{

View File

@ -11,10 +11,16 @@
namespace Symfony\Component\Security\Core\Util;
@trigger_error('The '.__NAMESPACE__.'\\StringUtils class is deprecated since version 2.8 and will be removed in 3.0. Use hash_equals() instead.', E_USER_DEPRECATED);
use Symfony\Component\Polyfill\Util\Binary;
/**
* String utility functions.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @deprecated since 2.8, to be removed in 3.0.
*/
class StringUtils
{
@ -47,25 +53,7 @@ class StringUtils
$userInput = (string) $userInput;
}
if (function_exists('hash_equals')) {
return hash_equals($knownString, $userInput);
}
$knownLen = self::safeStrlen($knownString);
$userLen = self::safeStrlen($userInput);
if ($userLen !== $knownLen) {
return false;
}
$result = 0;
for ($i = 0; $i < $knownLen; ++$i) {
$result |= (ord($knownString[$i]) ^ ord($userInput[$i]));
}
// They are only identical strings if $result is exactly 0...
return 0 === $result;
return hash_equals($knownString, $userInput);
}
/**
@ -77,17 +65,6 @@ class StringUtils
*/
public static function safeStrlen($string)
{
// Premature optimization
// Since this cannot be changed at runtime, we can cache it
static $funcExists = null;
if (null === $funcExists) {
$funcExists = function_exists('mb_strlen');
}
if ($funcExists) {
return mb_strlen($string, '8bit');
}
return strlen($string);
return Binary::strlen($string);
}
}

View File

@ -17,25 +17,25 @@
],
"require": {
"php": ">=5.3.9",
"paragonie/random_compat": "~1.0"
"symfony/polyfill-php55": "~1.0",
"symfony/polyfill-php56": "~1.0",
"symfony/polyfill-util": "~1.0"
},
"require-dev": {
"symfony/event-dispatcher": "~2.1|~3.0.0",
"symfony/expression-language": "~2.6|~3.0.0",
"symfony/http-foundation": "~2.4|~3.0.0",
"symfony/ldap": "~2.8|~3.0.0",
"symfony/translation": "~2.0,>=2.0.5|~3.0.0",
"symfony/validator": "~2.5,>=2.5.5|~3.0.0",
"psr/log": "~1.0",
"ircmaxell/password-compat": "1.0.*",
"symfony/ldap": "~2.8|~3.0.0"
"psr/log": "~1.0"
},
"suggest": {
"symfony/event-dispatcher": "",
"symfony/http-foundation": "",
"symfony/validator": "For using the user password constraint",
"symfony/expression-language": "For using the expression voter",
"symfony/ldap": "For using LDAP integration",
"ircmaxell/password-compat": "For using the BCrypt password encoder in PHP <5.5"
"symfony/ldap": "For using LDAP integration"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Security\\Core\\": "" }

View File

@ -11,7 +11,6 @@
namespace Symfony\Component\Security\Csrf;
use Symfony\Component\Security\Core\Util\StringUtils;
use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator;
use Symfony\Component\Security\Csrf\TokenGenerator\TokenGeneratorInterface;
use Symfony\Component\Security\Csrf\TokenStorage\NativeSessionTokenStorage;
@ -92,6 +91,6 @@ class CsrfTokenManager implements CsrfTokenManagerInterface
return false;
}
return StringUtils::equals($this->storage->getToken($token->getId()), $token->getValue());
return hash_equals($this->storage->getToken($token->getId()), $token->getValue());
}
}

View File

@ -17,8 +17,8 @@
],
"require": {
"php": ">=5.3.9",
"symfony/security-core": "~2.4|~3.0.0",
"paragonie/random_compat": "~1.0"
"symfony/polyfill-php56": "~1.0",
"symfony/security-core": "~2.4|~3.0.0"
},
"require-dev": {
"symfony/http-foundation": "~2.1|~3.0.0"

View File

@ -17,7 +17,6 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Util\StringUtils;
/**
* Concrete implementation of the RememberMeServicesInterface providing
@ -54,7 +53,7 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices
throw new \RuntimeException(sprintf('The UserProviderInterface implementation must return an instance of UserInterface, but returned "%s".', get_class($user)));
}
if (true !== StringUtils::equals($this->generateCookieHash($class, $username, $expires, $user->getPassword()), $hash)) {
if (true !== hash_equals($this->generateCookieHash($class, $username, $expires, $user->getPassword()), $hash)) {
throw new AuthenticationException('The cookie\'s hash is invalid.');
}

View File

@ -21,8 +21,9 @@
"symfony/event-dispatcher": "~2.1|~3.0.0",
"symfony/http-foundation": "~2.4|~3.0.0",
"symfony/http-kernel": "~2.4|~3.0.0",
"symfony/property-access": "~2.3|~3.0.0",
"paragonie/random_compat": "~1.0"
"symfony/polyfill-php56": "~1.0",
"symfony/polyfill-php70": "~1.0",
"symfony/property-access": "~2.3|~3.0.0"
},
"require-dev": {
"symfony/routing": "~2.2|~3.0.0",

View File

@ -21,8 +21,11 @@
"symfony/event-dispatcher": "~2.2|~3.0.0",
"symfony/http-foundation": "~2.1|~3.0.0",
"symfony/http-kernel": "~2.4|~3.0.0",
"symfony/property-access": "~2.3|~3.0.0",
"paragonie/random_compat": "~1.0"
"symfony/polyfill-php55": "~1.0",
"symfony/polyfill-php56": "~1.0",
"symfony/polyfill-php70": "~1.0",
"symfony/polyfill-util": "~1.0",
"symfony/property-access": "~2.3|~3.0.0"
},
"replace": {
"symfony/security-core": "self.version",
@ -32,14 +35,13 @@
},
"require-dev": {
"symfony/finder": "~2.3|~3.0.0",
"symfony/intl": "~2.3|~3.0.0",
"symfony/polyfill-intl-icu": "~1.0",
"symfony/routing": "~2.2|~3.0.0",
"symfony/translation": "~2.0,>=2.0.5|~3.0.0",
"symfony/validator": "~2.5,>=2.5.5|~3.0.0",
"doctrine/common": "~2.2",
"doctrine/dbal": "~2.2",
"psr/log": "~1.0",
"ircmaxell/password-compat": "~1.0",
"symfony/expression-language": "~2.6|~3.0.0",
"symfony/ldap": "~2.8|~3.0.0"
},
@ -50,7 +52,6 @@
"symfony/validator": "For using the user password constraint",
"symfony/routing": "For using the HttpUtils class to create sub-requests, redirect the user, and match URLs",
"symfony/expression-language": "For using the expression voter",
"ircmaxell/password-compat": "For using the BCrypt password encoder in PHP <5.5",
"symfony/ldap": "For using the LDAP user and authentication providers"
},
"autoload": {

View File

@ -108,7 +108,7 @@ class JsonDecode implements DecoderInterface
}
if (JSON_ERROR_NONE !== $this->lastError = json_last_error()) {
throw new UnexpectedValueException(JsonEncoder::getLastErrorMessage());
throw new UnexpectedValueException(json_last_error_message());
}
return $decodedData;

View File

@ -56,7 +56,7 @@ class JsonEncode implements EncoderInterface
$encodedJson = json_encode($data, $context['json_encode_options']);
if (JSON_ERROR_NONE !== $this->lastError = json_last_error()) {
throw new UnexpectedValueException(JsonEncoder::getLastErrorMessage());
throw new UnexpectedValueException(json_last_error_message());
}
return $encodedJson;

View File

@ -100,26 +100,13 @@ class JsonEncoder implements EncoderInterface, DecoderInterface
* Resolves json_last_error message.
*
* @return string
*
* @deprecated since 2.8, to be removed in 3.0. Use json_last_error_msg() instead.
*/
public static function getLastErrorMessage()
{
if (function_exists('json_last_error_msg')) {
return json_last_error_msg();
}
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use json_last_error_msg() instead.', E_USER_DEPRECATED);
switch (json_last_error()) {
case JSON_ERROR_DEPTH:
return 'Maximum stack depth exceeded';
case JSON_ERROR_STATE_MISMATCH:
return 'Underflow or the modes mismatch';
case JSON_ERROR_CTRL_CHAR:
return 'Unexpected control character found';
case JSON_ERROR_SYNTAX:
return 'Syntax error, malformed JSON';
case JSON_ERROR_UTF8:
return 'Malformed UTF-8 characters, possibly incorrectly encoded';
default:
return 'Unknown error';
}
return json_last_error_msg();
}
}

View File

@ -16,7 +16,8 @@
}
],
"require": {
"php": ">=5.3.9"
"php": ">=5.3.9",
"symfony/polyfill-php54": "~1.0"
},
"require-dev": {
"symfony/yaml": "~2.0,>=2.0.5|~3.0.0",

View File

@ -330,6 +330,9 @@ class PhpEngine implements EngineInterface, \ArrayAccess
*/
public function setCharset($charset)
{
if ('UTF8' === $charset = strtoupper($charset)) {
$charset = 'UTF-8'; // iconv on Windows requires "UTF-8" instead of "UTF8"
}
$this->charset = $charset;
foreach ($this->helpers as $helper) {
@ -448,7 +451,7 @@ class PhpEngine implements EngineInterface, \ArrayAccess
*/
function ($value) use ($that) {
if ('UTF-8' != $that->getCharset()) {
$value = $that->convertEncoding($value, 'UTF-8', $that->getCharset());
$value = iconv($that->getCharset(), 'UTF-8', $value);
}
$callback = function ($matches) use ($that) {
@ -460,7 +463,7 @@ class PhpEngine implements EngineInterface, \ArrayAccess
}
// \uHHHH
$char = $that->convertEncoding($char, 'UTF-16BE', 'UTF-8');
$char = iconv('UTF-8', 'UTF-16BE', $char);
return '\\u'.substr('0000'.bin2hex($char), -4);
};
@ -470,7 +473,7 @@ class PhpEngine implements EngineInterface, \ArrayAccess
}
if ('UTF-8' != $that->getCharset()) {
$value = $that->convertEncoding($value, $that->getCharset(), 'UTF-8');
$value = iconv('UTF-8', $that->getCharset(), $value);
}
return $value;
@ -489,17 +492,13 @@ class PhpEngine implements EngineInterface, \ArrayAccess
*
* @return string The string with the new encoding
*
* @throws \RuntimeException if no suitable encoding function is found (iconv or mbstring)
* @deprecated since 2.8, to be removed in 3.0. Use iconv() instead.
*/
public function convertEncoding($string, $to, $from)
{
if (function_exists('mb_convert_encoding')) {
return mb_convert_encoding($string, $to, $from);
} elseif (function_exists('iconv')) {
return iconv($from, $to, $string);
}
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use iconv() instead.', E_USER_DEPRECATED);
throw new \RuntimeException('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
return iconv($from, $to, $string);
}
/**

View File

@ -137,7 +137,7 @@ class TranslationDataCollector extends DataCollector implements LateDataCollecto
{
$string = trim(preg_replace('/\s+/', ' ', $string));
if (function_exists('mb_strlen') && false !== $encoding = mb_detect_encoding($string)) {
if (false !== $encoding = mb_detect_encoding($string, null, true)) {
if (mb_strlen($string, $encoding) > $length) {
return mb_substr($string, 0, $length - 3, $encoding).'...';
}

View File

@ -153,15 +153,7 @@ class XliffFileLoader implements LoaderInterface
private function utf8ToCharset($content, $encoding = null)
{
if ('UTF-8' !== $encoding && !empty($encoding)) {
if (function_exists('mb_convert_encoding')) {
return mb_convert_encoding($content, $encoding, 'UTF-8');
}
if (function_exists('iconv')) {
return iconv('UTF-8', $encoding, $content);
}
throw new \RuntimeException('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
return mb_convert_encoding($content, $encoding, 'UTF-8');
}
return $content;

View File

@ -16,9 +16,6 @@ use Symfony\Component\Translation\Dumper\IcuResFileDumper;
class IcuResFileDumperTest extends \PHPUnit_Framework_TestCase
{
/**
* @requires extension mbstring
*/
public function testFormatCatalogue()
{
$catalogue = new MessageCatalogue('en');

View File

@ -59,9 +59,6 @@ class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('foo' => 'bar', 'extra' => 'extra', 'key' => '', 'test' => 'with'), $catalogue->all('domain1'));
}
/**
* @requires extension mbstring
*/
public function testEncoding()
{
$loader = new XliffFileLoader();

View File

@ -16,7 +16,8 @@
}
],
"require": {
"php": ">=5.3.9"
"php": ">=5.3.9",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
"symfony/config": "~2.8",

View File

@ -42,29 +42,11 @@ class LengthValidator extends ConstraintValidator
$invalidCharset = false;
if ('UTF8' === $charset = strtoupper($constraint->charset)) {
$charset = 'UTF-8';
$charset = 'UTF-8'; // iconv on Windows requires "UTF-8" instead of "UTF8"
}
if ('UTF-8' === $charset) {
if (!preg_match('//u', $stringValue)) {
$invalidCharset = true;
} elseif (function_exists('utf8_decode')) {
$length = strlen(utf8_decode($stringValue));
} else {
preg_replace('/./u', '', $stringValue, -1, $length);
}
} elseif (function_exists('mb_strlen')) {
if (@mb_check_encoding($stringValue, $constraint->charset)) {
$length = mb_strlen($stringValue, $constraint->charset);
} else {
$invalidCharset = true;
}
} elseif (function_exists('iconv_strlen')) {
$length = @iconv_strlen($stringValue, $constraint->charset);
$invalidCharset = false === $length;
} else {
$length = strlen($stringValue);
}
$length = @iconv_strlen($stringValue, $charset);
$invalidCharset = false === $length;
if ($invalidCharset) {
if ($this->context instanceof ExecutionContextInterface) {

View File

@ -87,9 +87,6 @@ class LengthValidatorTest extends AbstractConstraintValidatorTest
);
}
/**
* @requires extension mbstring
*/
public function getOneCharset()
{
return array(

View File

@ -48,7 +48,7 @@ class CutStub extends Stub
case 'string':
$this->type = self::TYPE_STRING;
$this->class = preg_match('//u', $value) ? self::STRING_UTF8 : self::STRING_BINARY;
$this->cut = self::STRING_BINARY === $this->class ? strlen($value) : (function_exists('iconv_strlen') ? iconv_strlen($value, 'UTF-8') : -1);
$this->cut = self::STRING_BINARY === $this->class ? strlen($value) : mb_strlen($value, 'UTF-8');
$this->value = '';
break;
}

View File

@ -185,9 +185,6 @@ abstract class AbstractCloner implements ClonerInterface
$this->filter = $filter;
$this->prevErrorHandler = set_error_handler(array($this, 'handleError'));
try {
if (!function_exists('iconv')) {
$this->maxString = -1;
}
$data = $this->doClone($var);
} catch (\Exception $e) {
}

View File

@ -30,7 +30,6 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
protected $indentPad = ' ';
private $charset;
private $charsetConverter;
/**
* @param callable|resource|string|null $output A line dumper callable, an opened stream or an output path, defaults to static::$defaultOutput.
@ -82,29 +81,11 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
public function setCharset($charset)
{
$prev = $this->charset;
$this->charsetConverter = 'fallback';
$charset = strtoupper($charset);
$charset = null === $charset || 'UTF-8' === $charset || 'UTF8' === $charset ? 'CP1252' : $charset;
$supported = true;
set_error_handler(function () use (&$supported) {$supported = false;});
if (function_exists('mb_encoding_aliases') && mb_encoding_aliases($charset)) {
$this->charset = $charset;
$this->charsetConverter = 'mbstring';
} elseif (function_exists('iconv')) {
$supported = true;
iconv($charset, 'UTF-8', '');
if ($supported) {
$this->charset = $charset;
$this->charsetConverter = 'iconv';
}
}
if ('fallback' === $this->charsetConverter) {
$this->charset = 'ISO-8859-1';
}
restore_error_handler();
$this->charset = $charset;
return $prev;
}
@ -183,40 +164,13 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
*/
protected function utf8Encode($s)
{
if ('mbstring' === $this->charsetConverter) {
return mb_convert_encoding($s, 'UTF-8', mb_check_encoding($s, $this->charset) ? $this->charset : '8bit');
if (false !== $c = @iconv($this->charset, 'UTF-8', $s)) {
return $c;
}
if ('iconv' === $this->charsetConverter) {
$valid = true;
set_error_handler(function () use (&$valid) {$valid = false;});
$c = iconv($this->charset, 'UTF-8', $s);
restore_error_handler();
if ($valid) {
return $c;
}
if ('CP1252' !== $this->charset && false !== $c = @iconv('CP1252', 'UTF-8', $s)) {
return $c;
}
$s .= $s;
$len = strlen($s);
for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) {
switch (true) {
case $s[$i] < "\x80":
$s[$j] = $s[$i];
break;
case $s[$i] < "\xC0":
$s[$j] = "\xC2";
$s[++$j] = $s[$i];
break;
default:
$s[$j] = "\xC3";
$s[++$j] = chr(ord($s[$i]) - 64);
break;
}
}
return substr($s, 0, $j);
return iconv('CP850', 'UTF-8', $s);
}
}

View File

@ -91,9 +91,7 @@ class CliDumper extends AbstractDumper
*/
public function setMaxStringWidth($maxStringWidth)
{
if (function_exists('iconv')) {
$this->maxStringWidth = (int) $maxStringWidth;
}
$this->maxStringWidth = (int) $maxStringWidth;
}
/**
@ -171,7 +169,7 @@ class CliDumper extends AbstractDumper
$this->dumpLine($cursor->depth, true);
} else {
$attr = array(
'length' => 0 <= $cut && function_exists('iconv_strlen') ? iconv_strlen($str, 'UTF-8') + $cut : 0,
'length' => 0 <= $cut ? iconv_strlen($str, 'UTF-8') + $cut : 0,
'binary' => $bin,
);
$str = explode("\n", $str);

View File

@ -442,30 +442,7 @@ EOHTML;
}
$this->lastDepth = $depth;
// Replaces non-ASCII UTF-8 chars by numeric HTML entities
$this->line = preg_replace_callback(
'/[\x80-\xFF]+/',
function ($m) {
$m = unpack('C*', $m[0]);
$i = 1;
$entities = '';
while (isset($m[$i])) {
if (0xF0 <= $m[$i]) {
$c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
} elseif (0xE0 <= $m[$i]) {
$c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
} else {
$c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
}
$entities .= '&#'.$c.';';
}
return $entities;
},
$this->line
);
$this->line = mb_convert_encoding($this->line, 'HTML-ENTITIES', 'UTF-8');
if (-1 === $depth) {
AbstractDumper::dumpLine(0);

View File

@ -52,7 +52,7 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase
$closure54 = <<<EOTXT
<span class=sf-dump-meta>class</span>: "<span class=sf-dump-str title="48 characters">Symfony\Component\VarDumper\Tests\HtmlDumperTest</span>"
<span class=sf-dump-meta>this</span>: <abbr title="Symfony\Component\VarDumper\Tests\HtmlDumperTest" class=sf-dump-note>HtmlDumperTest</abbr> {{$r} &#8230;}
<span class=sf-dump-meta>this</span>: <abbr title="Symfony\Component\VarDumper\Tests\HtmlDumperTest" class=sf-dump-note>HtmlDumperTest</abbr> {{$r} &%s;}
EOTXT;
}
@ -68,8 +68,8 @@ EOTXT;
<span class=sf-dump-key>4</span> => <span class=sf-dump-num>INF</span>
<span class=sf-dump-key>5</span> => <span class=sf-dump-num>-INF</span>
<span class=sf-dump-key>6</span> => <span class=sf-dump-num>{$intMax}</span>
"<span class=sf-dump-key>str</span>" => "<span class=sf-dump-str title="5 characters">d&#233;j&#224;</span>\\n"
<span class=sf-dump-key>7</span> => b"<span class=sf-dump-str title="2 binary or non-UTF-8 characters">&#233;</span>\\x00"
"<span class=sf-dump-key>str</span>" => "<span class=sf-dump-str title="5 characters">d&%s;j&%s;</span>\\n"
<span class=sf-dump-key>7</span> => b"<span class=sf-dump-str title="2 binary or non-UTF-8 characters">&%s;</span>\\x00"
"<span class=sf-dump-key>[]</span>" => []
"<span class=sf-dump-key>res</span>" => <span class=sf-dump-note>stream resource</span> <a class=sf-dump-ref>@{$res}</a><samp>
<span class=sf-dump-meta>wrapper_type</span>: "<span class=sf-dump-str title="9 characters">plainfile</span>"
@ -109,7 +109,7 @@ EOTXT;
"<span class=sf-dump-key>snobj</span>" => <a class=sf-dump-ref href=#{$dumpId}-ref03 title="2 occurrences">&amp;3</a> {<a class=sf-dump-ref href=#{$dumpId}-ref2%d title="3 occurrences">#%d</a>}
"<span class=sf-dump-key>snobj2</span>" => {<a class=sf-dump-ref href=#{$dumpId}-ref2%d title="3 occurrences">#%d</a>}
"<span class=sf-dump-key>file</span>" => "<span class=sf-dump-str title="%d characters">{$var['file']}</span>"
b"<span class=sf-dump-key>bin-key-&#233;</span>" => ""
b"<span class=sf-dump-key>bin-key-&%s;</span>" => ""
</samp>]
</bar>
@ -120,9 +120,6 @@ EOTXT
);
}
/**
* @requires extension mbstring
*/
public function testCharset()
{
$var = mb_convert_encoding('Словарь', 'CP1251', 'UTF-8');

View File

@ -16,7 +16,8 @@
}
],
"require": {
"php": ">=5.3.9"
"php": ">=5.3.9",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
"twig/twig": "~1.20|~2.0"

View File

@ -52,7 +52,7 @@ class Inline
return '';
}
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('ASCII');
}

View File

@ -62,7 +62,7 @@ class Parser
$value = $this->cleanup($value);
$this->lines = explode("\n", $value);
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('UTF-8');
}