Issue #2571817 by Cottser, hussainweb: Remove race condition handling in TwigEnvironment::loadTemplate(), it's fixed upstream now
parent
bfcba53277
commit
dc95ff1c81
|
@ -17,7 +17,7 @@
|
|||
"symfony/validator": "2.7.*",
|
||||
"symfony/process": "2.7.*",
|
||||
"symfony/yaml": "2.7.*",
|
||||
"twig/twig": "~1.22",
|
||||
"twig/twig": "^1.22.2",
|
||||
"doctrine/common": "2.5.*",
|
||||
"doctrine/annotations": "1.2.*",
|
||||
"guzzlehttp/guzzle": "~6.1",
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "e917b58b5b2a847270d4bd49b0bcb22e",
|
||||
"content-hash": "bbb9004b899df99873971591682b1e42",
|
||||
"hash": "e6a3c80757f0e2a34ecc1cb9332cdab1",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
|
@ -1779,16 +1778,16 @@
|
|||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v1.22.1",
|
||||
"version": "v1.22.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "b7fc2469fa009897871fb95b68237286fc54a5ad"
|
||||
"reference": "79249fc8c9ff62e41e217e0c630e2e00bcadda6a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/b7fc2469fa009897871fb95b68237286fc54a5ad",
|
||||
"reference": "b7fc2469fa009897871fb95b68237286fc54a5ad",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/79249fc8c9ff62e41e217e0c630e2e00bcadda6a",
|
||||
"reference": "79249fc8c9ff62e41e217e0c630e2e00bcadda6a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1836,7 +1835,7 @@
|
|||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2015-09-15 06:50:16"
|
||||
"time": "2015-09-22 13:59:32"
|
||||
},
|
||||
{
|
||||
"name": "zendframework/zend-diactoros",
|
||||
|
@ -2169,7 +2168,7 @@
|
|||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/7e9a7319cc0e8cf9d4d4c9e06e2020d3a31bd792",
|
||||
"url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/c8e254f127d6f2242b994afd4339fb62d471df3f",
|
||||
"reference": "cc5ce119b5a8e06662f634b35967aff0b0c7dfdd",
|
||||
"shasum": ""
|
||||
},
|
||||
|
|
|
@ -67,56 +67,6 @@ class TwigEnvironment extends \Twig_Environment {
|
|||
parent::__construct($this->loader, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Twig_Environment::loadTemplate().
|
||||
*
|
||||
* We need to overwrite this function to integrate with drupal_php_storage().
|
||||
*
|
||||
* This is a straight copy from loadTemplate() changed to use
|
||||
* drupal_php_storage().
|
||||
*
|
||||
* @param string $name
|
||||
* The template name or the string which should be rendered as template.
|
||||
* @param int $index
|
||||
* The index if it is an embedded template.
|
||||
*
|
||||
* @return \Twig_TemplateInterface
|
||||
* A template instance representing the given template name.
|
||||
*
|
||||
* @throws \Twig_Error_Loader
|
||||
* When the template cannot be found.
|
||||
* @throws \Twig_Error_Syntax
|
||||
* When an error occurred during compilation.
|
||||
*/
|
||||
public function loadTemplate($name, $index = NULL) {
|
||||
$cls = $this->getTemplateClass($name, $index);
|
||||
|
||||
if (isset($this->loadedTemplates[$cls])) {
|
||||
return $this->loadedTemplates[$cls];
|
||||
}
|
||||
|
||||
if (!class_exists($cls, FALSE)) {
|
||||
$key = $this->cache->generateKey($name, $cls);
|
||||
|
||||
if (!$this->cache->has($key) || ($this->isAutoReload() && !$this->isTemplateFresh($name, $this->cache->getTimestamp($key)))) {
|
||||
$this->cache->write($key, $this->compileSource($this->getLoader()->getSource($name), $name));
|
||||
}
|
||||
|
||||
$this->cache->load($key);
|
||||
|
||||
if (!class_exists($cls, FALSE)) {
|
||||
$compiled_source = $this->compileSource($this->loader->getSource($name), $name);
|
||||
eval('?' . '>' . $compiled_source);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->runtimeInitialized) {
|
||||
$this->initRuntime();
|
||||
}
|
||||
|
||||
return $this->loadedTemplates[$cls] = new $cls($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the template class associated with the given string.
|
||||
*
|
||||
|
|
|
@ -78,13 +78,6 @@ class TwigPhpStorageCache implements \Twig_CacheInterface {
|
|||
return $this->templateCacheFilenamePrefix . '_' . basename($name) . '_' . $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key) {
|
||||
return $this->storage()->exists($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -592,7 +592,7 @@
|
|||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/7e9a7319cc0e8cf9d4d4c9e06e2020d3a31bd792",
|
||||
"url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/c8e254f127d6f2242b994afd4339fb62d471df3f",
|
||||
"reference": "cc5ce119b5a8e06662f634b35967aff0b0c7dfdd",
|
||||
"shasum": ""
|
||||
},
|
||||
|
@ -3418,17 +3418,17 @@
|
|||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v1.22.1",
|
||||
"version_normalized": "1.22.1.0",
|
||||
"version": "v1.22.2",
|
||||
"version_normalized": "1.22.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "b7fc2469fa009897871fb95b68237286fc54a5ad"
|
||||
"reference": "79249fc8c9ff62e41e217e0c630e2e00bcadda6a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/b7fc2469fa009897871fb95b68237286fc54a5ad",
|
||||
"reference": "b7fc2469fa009897871fb95b68237286fc54a5ad",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/79249fc8c9ff62e41e217e0c630e2e00bcadda6a",
|
||||
"reference": "79249fc8c9ff62e41e217e0c630e2e00bcadda6a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3438,7 +3438,7 @@
|
|||
"symfony/debug": "~2.7",
|
||||
"symfony/phpunit-bridge": "~2.7"
|
||||
},
|
||||
"time": "2015-09-15 06:50:16",
|
||||
"time": "2015-09-22 13:59:32",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
* 1.22.2 (2015-09-22)
|
||||
|
||||
* fixed a race condition in template loading
|
||||
|
||||
* 1.22.1 (2015-09-15)
|
||||
|
||||
* fixed regression in template_from_string
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#ifndef PHP_TWIG_H
|
||||
#define PHP_TWIG_H
|
||||
|
||||
#define PHP_TWIG_VERSION "1.22.1"
|
||||
#define PHP_TWIG_VERSION "1.22.2"
|
||||
|
||||
#include "php.h"
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ class Twig_Cache_Filesystem implements Twig_CacheInterface
|
|||
const FORCE_BYTECODE_INVALIDATION = 1;
|
||||
|
||||
private $directory;
|
||||
private $invalidateBytecode;
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* @param $directory string The root cache directory
|
||||
|
@ -41,20 +41,12 @@ class Twig_Cache_Filesystem implements Twig_CacheInterface
|
|||
return $this->directory.'/'.$hash[0].'/'.$hash[1].'/'.$hash.'.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return is_file($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($key)
|
||||
{
|
||||
require_once $key;
|
||||
@include_once $key;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -64,11 +56,8 @@ class Twig_Cache_Filesystem implements Twig_CacheInterface
|
|||
{
|
||||
$dir = dirname($key);
|
||||
if (!is_dir($dir)) {
|
||||
if (false === @mkdir($dir, 0777, true)) {
|
||||
clearstatcache(false, $dir);
|
||||
if (!is_dir($dir)) {
|
||||
throw new RuntimeException(sprintf('Unable to create the cache directory (%s).', $dir));
|
||||
}
|
||||
if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) {
|
||||
throw new RuntimeException(sprintf('Unable to create the cache directory (%s).', $dir));
|
||||
}
|
||||
} elseif (!is_writable($dir)) {
|
||||
throw new RuntimeException(sprintf('Unable to write in the cache directory (%s).', $dir));
|
||||
|
@ -98,6 +87,6 @@ class Twig_Cache_Filesystem implements Twig_CacheInterface
|
|||
*/
|
||||
public function getTimestamp($key)
|
||||
{
|
||||
return filemtime($key);
|
||||
return (int) @filemtime($key);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,20 +24,11 @@ class Twig_Cache_Null implements Twig_CacheInterface
|
|||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($key)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function write($key, $content)
|
||||
{
|
||||
eval('?>'.$content);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,7 +43,6 @@ class Twig_Cache_Null implements Twig_CacheInterface
|
|||
*/
|
||||
public function getTimestamp($key)
|
||||
{
|
||||
// never called as has() always returns false
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,15 +30,6 @@ interface Twig_CacheInterface
|
|||
*/
|
||||
public function generateKey($name, $className);
|
||||
|
||||
/**
|
||||
* Checks if the cache key exists.
|
||||
*
|
||||
* @param string $key The cache key
|
||||
*
|
||||
* @return bool true if the cache key exists, false otherwise
|
||||
*/
|
||||
public function has($key);
|
||||
|
||||
/**
|
||||
* Writes the compiled template to cache.
|
||||
*
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
class Twig_Environment
|
||||
{
|
||||
const VERSION = '1.22.1';
|
||||
const VERSION = '1.22.2';
|
||||
|
||||
protected $charset;
|
||||
protected $loader;
|
||||
|
@ -375,15 +375,20 @@ class Twig_Environment
|
|||
$key = $this->cache->generateKey($name, $cls);
|
||||
}
|
||||
|
||||
if (!$this->cache->has($key) || ($this->isAutoReload() && !$this->isTemplateFresh($name, $this->cache->getTimestamp($key)))) {
|
||||
if ($this->bcWriteCacheFile) {
|
||||
$this->writeCacheFile($key, $this->compileSource($this->getLoader()->getSource($name), $name));
|
||||
} else {
|
||||
$this->cache->write($key, $this->compileSource($this->getLoader()->getSource($name), $name));
|
||||
}
|
||||
if (!$this->isAutoReload() || $this->isTemplateFresh($name, $this->cache->getTimestamp($key))) {
|
||||
$this->cache->load($key);
|
||||
}
|
||||
|
||||
$this->cache->load($key);
|
||||
if (!class_exists($cls, false)) {
|
||||
$content = $this->compileSource($this->getLoader()->getSource($name), $name);
|
||||
if ($this->bcWriteCacheFile) {
|
||||
$this->writeCacheFile($key, $content);
|
||||
} else {
|
||||
$this->cache->write($key, $content);
|
||||
}
|
||||
|
||||
eval('?>'.$content);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->runtimeInitialized) {
|
||||
|
|
|
@ -885,6 +885,9 @@ function twig_split_filter(Twig_Environment $env, $value, $delimiter, $limit = n
|
|||
// The '_default' filter is used internally to avoid using the ternary operator
|
||||
// which costs a lot for big contexts (before PHP 5.4). So, on average,
|
||||
// a function call is cheaper.
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
function _twig_default_filter($value, $default = '')
|
||||
{
|
||||
if (twig_test_empty($value)) {
|
||||
|
@ -982,7 +985,9 @@ function twig_sort_filter($array)
|
|||
return $array;
|
||||
}
|
||||
|
||||
/* used internally */
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
function twig_in_filter($value, $compare)
|
||||
{
|
||||
if (is_array($compare)) {
|
||||
|
@ -1150,7 +1155,9 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
|
|||
}
|
||||
}
|
||||
|
||||
/* used internally */
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
function twig_escape_filter_is_safe(Twig_Node $filterArgs)
|
||||
{
|
||||
foreach ($filterArgs as $arg) {
|
||||
|
@ -1396,7 +1403,9 @@ else {
|
|||
}
|
||||
}
|
||||
|
||||
/* used internally */
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
function twig_ensure_traversable($seq)
|
||||
{
|
||||
if ($seq instanceof Traversable || is_array($seq)) {
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
* This class is used by Twig_Environment as a staging area and must not be used directly.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class Twig_Extension_Staging extends Twig_Extension
|
||||
{
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*
|
||||
* @deprecated since 1.18.1 (to be removed in 2.0)
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
|
||||
|
|
|
@ -61,6 +61,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|||
* @param array $context
|
||||
*
|
||||
* @return Twig_TemplateInterface|false The parent template or false if there is no parent
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function getParent(array $context)
|
||||
{
|
||||
|
@ -111,6 +113,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|||
* @param string $name The block name to display from the parent
|
||||
* @param array $context The context
|
||||
* @param array $blocks The current set of blocks
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function displayParentBlock($name, array $context, array $blocks = array())
|
||||
{
|
||||
|
@ -135,6 +139,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|||
* @param array $context The context
|
||||
* @param array $blocks The current set of blocks
|
||||
* @param bool $useBlocks Whether to use the current set of blocks
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function displayBlock($name, array $context, array $blocks = array(), $useBlocks = true)
|
||||
{
|
||||
|
@ -191,6 +197,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|||
* @param array $blocks The current set of blocks
|
||||
*
|
||||
* @return string The rendered block
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function renderParentBlock($name, array $context, array $blocks = array())
|
||||
{
|
||||
|
@ -212,6 +220,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|||
* @param bool $useBlocks Whether to use the current set of blocks
|
||||
*
|
||||
* @return string The rendered block
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function renderBlock($name, array $context, array $blocks = array(), $useBlocks = true)
|
||||
{
|
||||
|
@ -237,6 +247,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|||
* @param string $name The block name
|
||||
*
|
||||
* @return bool true if the block exists, false otherwise
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function hasBlock($name)
|
||||
{
|
||||
|
@ -252,6 +264,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|||
* @return array An array of block names
|
||||
*
|
||||
* @see hasBlock
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function getBlockNames()
|
||||
{
|
||||
|
@ -298,6 +312,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|||
* @return array An array of blocks
|
||||
*
|
||||
* @see hasBlock
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function getBlocks()
|
||||
{
|
||||
|
@ -407,6 +423,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
|
|||
* @return mixed The content of the context variable
|
||||
*
|
||||
* @throws Twig_Error_Runtime if the variable does not exist and Twig is running in strict mode
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final protected function getContext($context, $item, $ignoreStrictCheck = false)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue