wp/wp-includes/SimplePie/src/XML/Declaration/Parser.php
changeset 22 8c2e4d02f4ef
equal deleted inserted replaced
21:48c4eec2b7e6 22:8c2e4d02f4ef
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * SimplePie
       
     5  *
       
     6  * A PHP-Based RSS and Atom Feed Framework.
       
     7  * Takes the hard work out of managing a complete RSS/Atom solution.
       
     8  *
       
     9  * Copyright (c) 2004-2022, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
       
    10  * All rights reserved.
       
    11  *
       
    12  * Redistribution and use in source and binary forms, with or without modification, are
       
    13  * permitted provided that the following conditions are met:
       
    14  *
       
    15  * 	* Redistributions of source code must retain the above copyright notice, this list of
       
    16  * 	  conditions and the following disclaimer.
       
    17  *
       
    18  * 	* Redistributions in binary form must reproduce the above copyright notice, this list
       
    19  * 	  of conditions and the following disclaimer in the documentation and/or other materials
       
    20  * 	  provided with the distribution.
       
    21  *
       
    22  * 	* Neither the name of the SimplePie Team nor the names of its contributors may be used
       
    23  * 	  to endorse or promote products derived from this software without specific prior
       
    24  * 	  written permission.
       
    25  *
       
    26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
       
    27  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
       
    28  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
       
    29  * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
       
    30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
       
    31  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
       
    33  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
       
    34  * POSSIBILITY OF SUCH DAMAGE.
       
    35  *
       
    36  * @package SimplePie
       
    37  * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
       
    38  * @author Ryan Parman
       
    39  * @author Sam Sneddon
       
    40  * @author Ryan McCue
       
    41  * @link http://simplepie.org/ SimplePie
       
    42  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
       
    43  */
       
    44 
       
    45 namespace SimplePie\XML\Declaration;
       
    46 
       
    47 /**
       
    48  * Parses the XML Declaration
       
    49  *
       
    50  * @package SimplePie
       
    51  * @subpackage Parsing
       
    52  */
       
    53 class Parser
       
    54 {
       
    55     /**
       
    56      * XML Version
       
    57      *
       
    58      * @access public
       
    59      * @var string
       
    60      */
       
    61     public $version = '1.0';
       
    62 
       
    63     /**
       
    64      * Encoding
       
    65      *
       
    66      * @access public
       
    67      * @var string
       
    68      */
       
    69     public $encoding = 'UTF-8';
       
    70 
       
    71     /**
       
    72      * Standalone
       
    73      *
       
    74      * @access public
       
    75      * @var bool
       
    76      */
       
    77     public $standalone = false;
       
    78 
       
    79     private const STATE_BEFORE_VERSION_NAME = 'before_version_name';
       
    80 
       
    81     private const STATE_VERSION_NAME = 'version_name';
       
    82 
       
    83     private const STATE_VERSION_EQUALS = 'version_equals';
       
    84 
       
    85     private const STATE_VERSION_VALUE = 'version_value';
       
    86 
       
    87     private const STATE_ENCODING_NAME = 'encoding_name';
       
    88 
       
    89     private const STATE_EMIT = 'emit';
       
    90 
       
    91     private const STATE_ENCODING_EQUALS = 'encoding_equals';
       
    92 
       
    93     private const STATE_STANDALONE_NAME = 'standalone_name';
       
    94 
       
    95     private const STATE_ENCODING_VALUE = 'encoding_value';
       
    96 
       
    97     private const STATE_STANDALONE_EQUALS = 'standalone_equals';
       
    98 
       
    99     private const STATE_STANDALONE_VALUE = 'standalone_value';
       
   100 
       
   101     private const STATE_ERROR = false;
       
   102 
       
   103     /**
       
   104      * Current state of the state machine
       
   105      *
       
   106      * @access private
       
   107      * @var self::STATE_*
       
   108      */
       
   109     public $state = self::STATE_BEFORE_VERSION_NAME;
       
   110 
       
   111     /**
       
   112      * Input data
       
   113      *
       
   114      * @access private
       
   115      * @var string
       
   116      */
       
   117     public $data = '';
       
   118 
       
   119     /**
       
   120      * Input data length (to avoid calling strlen() everytime this is needed)
       
   121      *
       
   122      * @access private
       
   123      * @var int
       
   124      */
       
   125     public $data_length = 0;
       
   126 
       
   127     /**
       
   128      * Current position of the pointer
       
   129      *
       
   130      * @var int
       
   131      * @access private
       
   132      */
       
   133     public $position = 0;
       
   134 
       
   135     /**
       
   136      * Create an instance of the class with the input data
       
   137      *
       
   138      * @access public
       
   139      * @param string $data Input data
       
   140      */
       
   141     public function __construct($data)
       
   142     {
       
   143         $this->data = $data;
       
   144         $this->data_length = strlen($this->data);
       
   145     }
       
   146 
       
   147     /**
       
   148      * Parse the input data
       
   149      *
       
   150      * @access public
       
   151      * @return bool true on success, false on failure
       
   152      */
       
   153     public function parse()
       
   154     {
       
   155         while ($this->state && $this->state !== self::STATE_EMIT && $this->has_data()) {
       
   156             $state = $this->state;
       
   157             $this->$state();
       
   158         }
       
   159         $this->data = '';
       
   160         if ($this->state === self::STATE_EMIT) {
       
   161             return true;
       
   162         }
       
   163 
       
   164         $this->version = '';
       
   165         $this->encoding = '';
       
   166         $this->standalone = '';
       
   167         return false;
       
   168     }
       
   169 
       
   170     /**
       
   171      * Check whether there is data beyond the pointer
       
   172      *
       
   173      * @access private
       
   174      * @return bool true if there is further data, false if not
       
   175      */
       
   176     public function has_data()
       
   177     {
       
   178         return (bool) ($this->position < $this->data_length);
       
   179     }
       
   180 
       
   181     /**
       
   182      * Advance past any whitespace
       
   183      *
       
   184      * @return int Number of whitespace characters passed
       
   185      */
       
   186     public function skip_whitespace()
       
   187     {
       
   188         $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
       
   189         $this->position += $whitespace;
       
   190         return $whitespace;
       
   191     }
       
   192 
       
   193     /**
       
   194      * Read value
       
   195      */
       
   196     public function get_value()
       
   197     {
       
   198         $quote = substr($this->data, $this->position, 1);
       
   199         if ($quote === '"' || $quote === "'") {
       
   200             $this->position++;
       
   201             $len = strcspn($this->data, $quote, $this->position);
       
   202             if ($this->has_data()) {
       
   203                 $value = substr($this->data, $this->position, $len);
       
   204                 $this->position += $len + 1;
       
   205                 return $value;
       
   206             }
       
   207         }
       
   208         return false;
       
   209     }
       
   210 
       
   211     public function before_version_name()
       
   212     {
       
   213         if ($this->skip_whitespace()) {
       
   214             $this->state = self::STATE_VERSION_NAME;
       
   215         } else {
       
   216             $this->state = self::STATE_ERROR;
       
   217         }
       
   218     }
       
   219 
       
   220     public function version_name()
       
   221     {
       
   222         if (substr($this->data, $this->position, 7) === 'version') {
       
   223             $this->position += 7;
       
   224             $this->skip_whitespace();
       
   225             $this->state = self::STATE_VERSION_EQUALS;
       
   226         } else {
       
   227             $this->state = self::STATE_ERROR;
       
   228         }
       
   229     }
       
   230 
       
   231     public function version_equals()
       
   232     {
       
   233         if (substr($this->data, $this->position, 1) === '=') {
       
   234             $this->position++;
       
   235             $this->skip_whitespace();
       
   236             $this->state = self::STATE_VERSION_VALUE;
       
   237         } else {
       
   238             $this->state = self::STATE_ERROR;
       
   239         }
       
   240     }
       
   241 
       
   242     public function version_value()
       
   243     {
       
   244         if ($this->version = $this->get_value()) {
       
   245             $this->skip_whitespace();
       
   246             if ($this->has_data()) {
       
   247                 $this->state = self::STATE_ENCODING_NAME;
       
   248             } else {
       
   249                 $this->state = self::STATE_EMIT;
       
   250             }
       
   251         } else {
       
   252             $this->state = self::STATE_ERROR;
       
   253         }
       
   254     }
       
   255 
       
   256     public function encoding_name()
       
   257     {
       
   258         if (substr($this->data, $this->position, 8) === 'encoding') {
       
   259             $this->position += 8;
       
   260             $this->skip_whitespace();
       
   261             $this->state = self::STATE_ENCODING_EQUALS;
       
   262         } else {
       
   263             $this->state = self::STATE_STANDALONE_NAME;
       
   264         }
       
   265     }
       
   266 
       
   267     public function encoding_equals()
       
   268     {
       
   269         if (substr($this->data, $this->position, 1) === '=') {
       
   270             $this->position++;
       
   271             $this->skip_whitespace();
       
   272             $this->state = self::STATE_ENCODING_VALUE;
       
   273         } else {
       
   274             $this->state = self::STATE_ERROR;
       
   275         }
       
   276     }
       
   277 
       
   278     public function encoding_value()
       
   279     {
       
   280         if ($this->encoding = $this->get_value()) {
       
   281             $this->skip_whitespace();
       
   282             if ($this->has_data()) {
       
   283                 $this->state = self::STATE_STANDALONE_NAME;
       
   284             } else {
       
   285                 $this->state = self::STATE_EMIT;
       
   286             }
       
   287         } else {
       
   288             $this->state = self::STATE_ERROR;
       
   289         }
       
   290     }
       
   291 
       
   292     public function standalone_name()
       
   293     {
       
   294         if (substr($this->data, $this->position, 10) === 'standalone') {
       
   295             $this->position += 10;
       
   296             $this->skip_whitespace();
       
   297             $this->state = self::STATE_STANDALONE_EQUALS;
       
   298         } else {
       
   299             $this->state = self::STATE_ERROR;
       
   300         }
       
   301     }
       
   302 
       
   303     public function standalone_equals()
       
   304     {
       
   305         if (substr($this->data, $this->position, 1) === '=') {
       
   306             $this->position++;
       
   307             $this->skip_whitespace();
       
   308             $this->state = self::STATE_STANDALONE_VALUE;
       
   309         } else {
       
   310             $this->state = self::STATE_ERROR;
       
   311         }
       
   312     }
       
   313 
       
   314     public function standalone_value()
       
   315     {
       
   316         if ($standalone = $this->get_value()) {
       
   317             switch ($standalone) {
       
   318                 case 'yes':
       
   319                     $this->standalone = true;
       
   320                     break;
       
   321 
       
   322                 case 'no':
       
   323                     $this->standalone = false;
       
   324                     break;
       
   325 
       
   326                 default:
       
   327                     $this->state = self::STATE_ERROR;
       
   328                     return;
       
   329             }
       
   330 
       
   331             $this->skip_whitespace();
       
   332             if ($this->has_data()) {
       
   333                 $this->state = self::STATE_ERROR;
       
   334             } else {
       
   335                 $this->state = self::STATE_EMIT;
       
   336             }
       
   337         } else {
       
   338             $this->state = self::STATE_ERROR;
       
   339         }
       
   340     }
       
   341 }
       
   342 
       
   343 class_alias('SimplePie\XML\Declaration\Parser', 'SimplePie_XML_Declaration_Parser');