From d5dbc59a4cc8e82b7608fbf5290f9e21525fb75c Mon Sep 17 00:00:00 2001 From: madflow Date: Mon, 25 Sep 2017 17:21:12 +0200 Subject: [PATCH 01/10] (chore) Fix the Travis build --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 99de817..05d997c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,9 @@ sudo: false matrix: include: - php: 5.2 + dist: precise - php: 5.3 + dist: precise - php: 5.4 - php: 5.5 - php: 5.6 From d65edafb85a5cae558b378174e0acd3e892f13ba Mon Sep 17 00:00:00 2001 From: Thomas Gerbet Date: Fri, 8 Dec 2017 17:15:07 +0100 Subject: [PATCH 02/10] Run tests against PHP 7.2 on Travis CI PHP 7.2 has been released as a stable version [1] [1] https://secure.php.net/archive/2017.php#id2017-11-30-1 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 05d997c..7d97d8c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ matrix: - php: 5.6 - php: 7.0 - php: 7.1 + - php: 7.2 - php: hhvm dist: trusty From bbb43caa1a619ddb8da943146c3e24d543e09335 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sun, 21 Jul 2019 15:37:32 -0700 Subject: [PATCH 03/10] Fix delimiter parse error, and throw a syntax error when invalid. The mustache spec has a test case that _should_ have caught this: https://github.com/mustache/spec/blob/master/specs/delimiters.yml#L154-L158 ... But that test case only tests that an engine recognizes it as a delimiter change tag, not that it ends up changing to the correct delimiters. In our case, we were incorrectly changing to `@` and ` `. The only "invalid" case I can think of is missing delimiters, which is how that spec test was (incorrectly) parsed. Now it'll enforce that it's always called with *something* that can be used as a delimiter. --- src/Mustache/Tokenizer.php | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Mustache/Tokenizer.php b/src/Mustache/Tokenizer.php index b1f3d73..daecb7f 100644 --- a/src/Mustache/Tokenizer.php +++ b/src/Mustache/Tokenizer.php @@ -81,6 +81,7 @@ class Mustache_Tokenizer * Scan and tokenize template source. * * @throws Mustache_Exception_SyntaxException when mismatched section tags are encountered + * @throws Mustache_Exception_InvalidArgumentException when $delimiters string is invalid * * @param string $text Mustache template source to tokenize * @param string $delimiters Optionally, pass initial opening and closing delimiters (default: null) @@ -249,6 +250,8 @@ class Mustache_Tokenizer /** * Change the current Mustache delimiters. Set new `otag` and `ctag` values. * + * @throws Mustache_Exception_SyntaxException when delimiter string is invalid + * * @param string $text Mustache template source * @param int $index Current tokenizer index * @@ -260,24 +263,37 @@ class Mustache_Tokenizer $close = '=' . $this->ctag; $closeIndex = strpos($text, $close, $index); - $this->setDelimiters(trim(substr($text, $startIndex, $closeIndex - $startIndex))); - - $this->tokens[] = array( + $token = array( self::TYPE => self::T_DELIM_CHANGE, self::LINE => $this->line, ); + try { + $this->setDelimiters(trim(substr($text, $startIndex, $closeIndex - $startIndex))); + } catch (Mustache_Exception_InvalidArgumentException $e) { + throw new Mustache_Exception_SyntaxException($e->getMessage(), $token); + } + + $this->tokens[] = $token; + return $closeIndex + strlen($close) - 1; } /** * Set the current Mustache `otag` and `ctag` delimiters. * + * @throws Mustache_Exception_InvalidArgumentException when delimiter string is invalid + * * @param string $delimiters */ private function setDelimiters($delimiters) { - list($otag, $ctag) = explode(' ', $delimiters); + if (!preg_match('/^\s*(\S+)\s+(\S+)\s*$/', $delimiters, $matches)) { + throw new Mustache_Exception_InvalidArgumentException(sprintf('Invalid delimiters: %s', $delimiters)); + } + + list($_, $otag, $ctag) = $matches; + $this->otag = $otag; $this->ctag = $ctag; $this->otagLen = strlen($otag); From 72d07520ec171c403f2d6d26a3ca33fa95be2c52 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sun, 21 Jul 2019 16:01:49 -0700 Subject: [PATCH 04/10] Improve Tokenizer::scan performance by 98.2%. - Checking the first character of the opening and closing tags is >90% faster than baseline for my test case. - Inlining the `tagChange` method is 18% faster than baseline. - Together they yield a 98.2% wall clock time improvement! Hat tip to @sam-osborne for the first one :) https://github.com/mardix/Handlebars/pull/6 --- src/Mustache/Tokenizer.php | 67 +++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/src/Mustache/Tokenizer.php b/src/Mustache/Tokenizer.php index daecb7f..6dbe0cd 100644 --- a/src/Mustache/Tokenizer.php +++ b/src/Mustache/Tokenizer.php @@ -72,9 +72,13 @@ class Mustache_Tokenizer private $tokens; private $seenTag; private $line; + private $otag; - private $ctag; + private $otagChar; private $otagLen; + + private $ctag; + private $ctagChar; private $ctagLen; /** @@ -111,12 +115,13 @@ class Mustache_Tokenizer for ($i = 0; $i < $len; $i++) { switch ($this->state) { case self::IN_TEXT: - if ($this->tagChange($this->otag, $this->otagLen, $text, $i)) { + $char = $text[$i]; + // Test whether it's time to change tags. + if ($char === $this->otagChar && substr($text, $i, $this->otagLen) === $this->otag) { $i--; $this->flushBuffer(); $this->state = self::IN_TAG_TYPE; } else { - $char = $text[$i]; $this->buffer .= $char; if ($char === "\n") { $this->flushBuffer(); @@ -152,7 +157,9 @@ class Mustache_Tokenizer break; default: - if ($this->tagChange($this->ctag, $this->ctagLen, $text, $i)) { + $char = $text[$i]; + // Test whether it's time to change tags. + if ($char === $this->ctagChar && substr($text, $i, $this->ctagLen) === $this->ctag) { $token = array( self::TYPE => $this->tagType, self::NAME => trim($this->buffer), @@ -197,7 +204,7 @@ class Mustache_Tokenizer $this->state = self::IN_TEXT; $this->tokens[] = $token; } else { - $this->buffer .= $text[$i]; + $this->buffer .= $char; } break; } @@ -220,16 +227,20 @@ class Mustache_Tokenizer */ private function reset() { - $this->state = self::IN_TEXT; - $this->tagType = null; - $this->buffer = ''; - $this->tokens = array(); - $this->seenTag = false; - $this->line = 0; - $this->otag = '{{'; - $this->ctag = '}}'; - $this->otagLen = 2; - $this->ctagLen = 2; + $this->state = self::IN_TEXT; + $this->tagType = null; + $this->buffer = ''; + $this->tokens = array(); + $this->seenTag = false; + $this->line = 0; + + $this->otag = '{{'; + $this->otagChar = '{'; + $this->otagLen = 2; + + $this->ctag = '}}'; + $this->ctagChar = '}'; + $this->ctagLen = 2; } /** @@ -294,10 +305,13 @@ class Mustache_Tokenizer list($_, $otag, $ctag) = $matches; - $this->otag = $otag; - $this->ctag = $ctag; - $this->otagLen = strlen($otag); - $this->ctagLen = strlen($ctag); + $this->otag = $otag; + $this->otagChar = $otag[0]; + $this->otagLen = strlen($otag); + + $this->ctag = $ctag; + $this->ctagChar = $ctag[0]; + $this->ctagLen = strlen($ctag); } /** @@ -325,19 +339,4 @@ class Mustache_Tokenizer return $end + $this->ctagLen - 1; } - - /** - * Test whether it's time to change tags. - * - * @param string $tag Current tag name - * @param int $tagLen Current tag name length - * @param string $text Mustache template source - * @param int $index Current tokenizer index - * - * @return bool True if this is a closing section tag - */ - private function tagChange($tag, $tagLen, $text, $index) - { - return substr($text, $index, $tagLen) === $tag; - } } From 4c28410c3a3522450ab13a05e92e7ca824741c6c Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sun, 21 Jul 2019 22:34:20 -0700 Subject: [PATCH 05/10] Let HHVM fail /shrug --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7d97d8c..12f4b4d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,9 +16,11 @@ matrix: - php: 7.2 - php: hhvm dist: trusty + allow_failures: + - php: hhvm script: - - '[[ "$TRAVIS_PHP_VERSION" = 5.2* ]] && phpunit || vendor/bin/phpunit --verbose' + - '[[ "$TRAVIS_PHP_VERSION" = 5.2* ]] && phpunit || vendor/bin/phpunit --verbose' install: - - '[[ "$TRAVIS_PHP_VERSION" = 5.2* ]] || composer install' + - '[[ "$TRAVIS_PHP_VERSION" = 5.2* ]] || composer install' From 916b13e060dbd26b734113242639c2d8122f12ca Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sat, 23 Nov 2019 10:28:42 -0800 Subject: [PATCH 06/10] Fix PHP 5.4 and 5.5 on CI --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 12f4b4d..8b67b21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,9 @@ matrix: - php: 5.3 dist: precise - php: 5.4 + dist: trusty - php: 5.5 + dist: trusty - php: 5.6 - php: 7.0 - php: 7.1 From 778906301cca57c27bf6446b47c775d034bffc50 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sat, 23 Nov 2019 10:31:10 -0800 Subject: [PATCH 07/10] Moar PHPs! --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 8b67b21..14ef706 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,8 @@ matrix: - php: 7.0 - php: 7.1 - php: 7.2 + - php: 7.3 + - php: 7.4snapshot - php: hhvm dist: trusty allow_failures: From 6d28b0b28d941ac766092b13f65e56d63b782154 Mon Sep 17 00:00:00 2001 From: Joyce Babu Date: Sun, 17 Nov 2019 23:18:01 +0530 Subject: [PATCH 08/10] Prevent array access on null value Fix 'Trying to access array offset on value of type null' notice on PHP 7.4 --- src/Mustache/Parser.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Mustache/Parser.php b/src/Mustache/Parser.php index c36a84a..0ec4192 100644 --- a/src/Mustache/Parser.php +++ b/src/Mustache/Parser.php @@ -149,7 +149,7 @@ class Mustache_Parser case Mustache_Tokenizer::T_BLOCK_VAR: if ($this->pragmaBlocks) { // BLOCKS pragma is enabled, let's do this! - if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) { + if (isset($parent) && $parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) { $token[Mustache_Tokenizer::TYPE] = Mustache_Tokenizer::T_BLOCK_ARG; } $this->clearStandaloneLines($nodes, $tokens); @@ -275,7 +275,7 @@ class Mustache_Parser */ private function checkIfTokenIsAllowedInParent($parent, array $token) { - if ($parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) { + if (isset($parent) && $parent[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_PARENT) { throw new Mustache_Exception_SyntaxException('Illegal content in < parent tag', $token); } } From a04f70e8b5b4eb76bd7e74bf65dee7e91550ae30 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sat, 23 Nov 2019 10:51:33 -0800 Subject: [PATCH 09/10] Let 7.4 snapshot fail for now --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 14ef706..d88c6f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,7 @@ matrix: dist: trusty allow_failures: - php: hhvm + - php: 7.4snapshot script: - '[[ "$TRAVIS_PHP_VERSION" = 5.2* ]] && phpunit || vendor/bin/phpunit --verbose' From 819a3e1e46cd09d7f5d7ecc0412d136cadd0a9f6 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Sat, 23 Nov 2019 13:38:47 -0800 Subject: [PATCH 10/10] Bump to v2.13.0 --- src/Mustache/Engine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mustache/Engine.php b/src/Mustache/Engine.php index 9110977..fe99799 100644 --- a/src/Mustache/Engine.php +++ b/src/Mustache/Engine.php @@ -23,7 +23,7 @@ */ class Mustache_Engine { - const VERSION = '2.12.0'; + const VERSION = '2.13.0'; const SPEC_VERSION = '1.1.2'; const PRAGMA_FILTERS = 'FILTERS';