Blame view

vendor/ezyang/htmlpurifier/library/HTMLPurifier/PercentEncoder.php 3.48 KB
abf1649b   andryeyev   Чистая установка ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  <?php
  
  /**
   * Class that handles operations involving percent-encoding in URIs.
   *
   * @warning
   *      Be careful when reusing instances of PercentEncoder. The object
   *      you use for normalize() SHOULD NOT be used for encode(), or
   *      vice-versa.
   */
  class HTMLPurifier_PercentEncoder
  {
  
      /**
       * Reserved characters to preserve when using encode().
       * @type array
       */
      protected $preserve = array();
  
      /**
       * String of characters that should be preserved while using encode().
       * @param bool $preserve
       */
      public function __construct($preserve = false)
      {
          // unreserved letters, ought to const-ify
          for ($i = 48; $i <= 57; $i++) { // digits
              $this->preserve[$i] = true;
          }
          for ($i = 65; $i <= 90; $i++) { // upper-case
              $this->preserve[$i] = true;
          }
          for ($i = 97; $i <= 122; $i++) { // lower-case
              $this->preserve[$i] = true;
          }
          $this->preserve[45] = true; // Dash         -
          $this->preserve[46] = true; // Period       .
          $this->preserve[95] = true; // Underscore   _
          $this->preserve[126]= true; // Tilde        ~
  
          // extra letters not to escape
          if ($preserve !== false) {
              for ($i = 0, $c = strlen($preserve); $i < $c; $i++) {
                  $this->preserve[ord($preserve[$i])] = true;
              }
          }
      }
  
      /**
       * Our replacement for urlencode, it encodes all non-reserved characters,
       * as well as any extra characters that were instructed to be preserved.
       * @note
       *      Assumes that the string has already been normalized, making any
       *      and all percent escape sequences valid. Percents will not be
       *      re-escaped, regardless of their status in $preserve
       * @param string $string String to be encoded
       * @return string Encoded string.
       */
      public function encode($string)
      {
          $ret = '';
          for ($i = 0, $c = strlen($string); $i < $c; $i++) {
              if ($string[$i] !== '%' && !isset($this->preserve[$int = ord($string[$i])])) {
                  $ret .= '%' . sprintf('%02X', $int);
              } else {
                  $ret .= $string[$i];
              }
          }
          return $ret;
      }
  
      /**
       * Fix up percent-encoding by decoding unreserved characters and normalizing.
       * @warning This function is affected by $preserve, even though the
       *          usual desired behavior is for this not to preserve those
       *          characters. Be careful when reusing instances of PercentEncoder!
       * @param string $string String to normalize
       * @return string
       */
      public function normalize($string)
      {
          if ($string == '') {
              return '';
          }
          $parts = explode('%', $string);
          $ret = array_shift($parts);
          foreach ($parts as $part) {
              $length = strlen($part);
              if ($length < 2) {
                  $ret .= '%25' . $part;
                  continue;
              }
              $encoding = substr($part, 0, 2);
              $text     = substr($part, 2);
              if (!ctype_xdigit($encoding)) {
                  $ret .= '%25' . $part;
                  continue;
              }
              $int = hexdec($encoding);
              if (isset($this->preserve[$int])) {
                  $ret .= chr($int) . $text;
                  continue;
              }
              $encoding = strtoupper($encoding);
              $ret .= '%' . $encoding . $text;
          }
          return $ret;
      }
  }
  
  // vim: et sw=4 sts=4