Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 39 and 311]

   1  <?php
   2  
   3  /**
   4   * This file is part of FPDI
   5   *
   6   * @package   setasign\Fpdi
   7   * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
   8   * @license   http://opensource.org/licenses/mit-license The MIT License
   9   */
  10  
  11  namespace setasign\Fpdi\PdfParser\Type;
  12  
  13  use setasign\Fpdi\PdfParser\StreamReader;
  14  
  15  /**
  16   * Class representing a PDF string object
  17   */
  18  class PdfString extends PdfType
  19  {
  20      /**
  21       * Parses a string object from the stream reader.
  22       *
  23       * @param StreamReader $streamReader
  24       * @return self
  25       */
  26      public static function parse(StreamReader $streamReader)
  27      {
  28          $pos = $startPos = $streamReader->getOffset();
  29          $openBrackets = 1;
  30          do {
  31              $buffer = $streamReader->getBuffer(false);
  32              for ($length = \strlen($buffer); $openBrackets !== 0 && $pos < $length; $pos++) {
  33                  switch ($buffer[$pos]) {
  34                      case '(':
  35                          $openBrackets++;
  36                          break;
  37                      case ')':
  38                          $openBrackets--;
  39                          break;
  40                      case '\\':
  41                          $pos++;
  42                  }
  43              }
  44          } while ($openBrackets !== 0 && $streamReader->increaseLength());
  45  
  46          $result = \substr($buffer, $startPos, $openBrackets + $pos - $startPos - 1);
  47          $streamReader->setOffset($pos);
  48  
  49          $v = new self();
  50          $v->value = $result;
  51  
  52          return $v;
  53      }
  54  
  55      /**
  56       * Helper method to create an instance.
  57       *
  58       * @param string $value The string needs to be escaped accordingly.
  59       * @return self
  60       */
  61      public static function create($value)
  62      {
  63          $v = new self();
  64          $v->value = $value;
  65  
  66          return $v;
  67      }
  68  
  69      /**
  70       * Ensures that the passed value is a PdfString instance.
  71       *
  72       * @param mixed $string
  73       * @return self
  74       * @throws PdfTypeException
  75       */
  76      public static function ensure($string)
  77      {
  78          return PdfType::ensureType(self::class, $string, 'String value expected.');
  79      }
  80  
  81      /**
  82       * Unescapes escaped sequences in a PDF string according to the PDF specification.
  83       *
  84       * @param string $s
  85       * @return string
  86       */
  87      public static function unescape($s)
  88      {
  89          $out = '';
  90          /** @noinspection ForeachInvariantsInspection */
  91          for ($count = 0, $n = \strlen($s); $count < $n; $count++) {
  92              if ($s[$count] !== '\\') {
  93                  $out .= $s[$count];
  94              } else {
  95                  // A backslash at the end of the string - ignore it
  96                  if ($count === ($n - 1)) {
  97                      break;
  98                  }
  99  
 100                  switch ($s[++$count]) {
 101                      case ')':
 102                      case '(':
 103                      case '\\':
 104                          $out .= $s[$count];
 105                          break;
 106  
 107                      case 'f':
 108                          $out .= "\x0C";
 109                          break;
 110  
 111                      case 'b':
 112                          $out .= "\x08";
 113                          break;
 114  
 115                      case 't':
 116                          $out .= "\x09";
 117                          break;
 118  
 119                      case 'r':
 120                          $out .= "\x0D";
 121                          break;
 122  
 123                      case 'n':
 124                          $out .= "\x0A";
 125                          break;
 126  
 127                      case "\r":
 128                          if ($count !== $n - 1 && $s[$count + 1] === "\n") {
 129                              $count++;
 130                          }
 131                          break;
 132  
 133                      case "\n":
 134                          break;
 135  
 136                      default:
 137                          $actualChar = \ord($s[$count]);
 138                          // ascii 48 = number 0
 139                          // ascii 57 = number 9
 140                          if ($actualChar >= 48 && $actualChar <= 57) {
 141                              $oct = '' . $s[$count];
 142  
 143                              /** @noinspection NotOptimalIfConditionsInspection */
 144                              if (
 145                                  $count + 1 < $n
 146                                  && \ord($s[$count + 1]) >= 48
 147                                  && \ord($s[$count + 1]) <= 57
 148                              ) {
 149                                  $count++;
 150                                  $oct .= $s[$count];
 151  
 152                                  /** @noinspection NotOptimalIfConditionsInspection */
 153                                  if (
 154                                      $count + 1 < $n
 155                                      && \ord($s[$count + 1]) >= 48
 156                                      && \ord($s[$count + 1]) <= 57
 157                                  ) {
 158                                      $oct .= $s[++$count];
 159                                  }
 160                              }
 161  
 162                              $out .= \chr(\octdec($oct));
 163                          } else {
 164                              // If the character is not one of those defined, the backslash is ignored
 165                              $out .= $s[$count];
 166                          }
 167                  }
 168              }
 169          }
 170          return $out;
 171      }
 172  }