فهرست منبع

Merge branch 'release/2.13.0'

Justin Hileman 6 سال پیش
والد
کامیت
c33bda0eed
4فایلهای تغییر یافته به همراه68 افزوده شده و 43 حذف شده
  1. 12 2
      .travis.yml
  2. 1 1
      src/Mustache/Engine.php
  3. 2 2
      src/Mustache/Parser.php
  4. 53 38
      src/Mustache/Tokenizer.php

+ 12 - 2
.travis.yml

@@ -5,17 +5,27 @@ sudo: false
 matrix:
   include:
     - php: 5.2
+      dist: precise
     - php: 5.3
+      dist: precise
     - php: 5.4
+      dist: trusty
     - php: 5.5
+      dist: trusty
     - php: 5.6
     - php: 7.0
     - php: 7.1
+    - php: 7.2
+    - php: 7.3
+    - php: 7.4snapshot
     - php: hhvm
       dist: trusty
+  allow_failures:
+    - php: hhvm
+    - php: 7.4snapshot
 
 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'

+ 1 - 1
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';

+ 2 - 2
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);
         }
     }

+ 53 - 38
src/Mustache/Tokenizer.php

@@ -72,15 +72,20 @@ class Mustache_Tokenizer
     private $tokens;
     private $seenTag;
     private $line;
+
     private $otag;
-    private $ctag;
+    private $otagChar;
     private $otagLen;
+
+    private $ctag;
+    private $ctagChar;
     private $ctagLen;
 
     /**
      * 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)
@@ -110,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();
@@ -151,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),
@@ -196,7 +204,7 @@ class Mustache_Tokenizer
                         $this->state = self::IN_TEXT;
                         $this->tokens[] = $token;
                     } else {
-                        $this->buffer .= $text[$i];
+                        $this->buffer .= $char;
                     }
                     break;
             }
@@ -219,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;
     }
 
     /**
@@ -249,6 +261,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,28 +274,44 @@ 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);
-        $this->otag = $otag;
-        $this->ctag = $ctag;
-        $this->otagLen = strlen($otag);
-        $this->ctagLen = strlen($ctag);
+        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->otagChar = $otag[0];
+        $this->otagLen  = strlen($otag);
+
+        $this->ctag     = $ctag;
+        $this->ctagChar = $ctag[0];
+        $this->ctagLen  = strlen($ctag);
     }
 
     /**
@@ -309,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;
-    }
 }