Upgraded drupal core with security updates
[yaffs-website] / web / core / lib / Drupal / Component / Serialization / YamlPecl.php
1 <?php
2
3 namespace Drupal\Component\Serialization;
4
5 use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
6
7 /**
8  * Provides default serialization for YAML using the PECL extension.
9  */
10 class YamlPecl implements SerializationInterface {
11
12   /**
13    * {@inheritdoc}
14    */
15   public static function encode($data) {
16     static $init;
17     if (!isset($init)) {
18       ini_set('yaml.output_indent', 2);
19       // Do not break lines at 80 characters.
20       ini_set('yaml.output_width', -1);
21       $init = TRUE;
22     }
23     return yaml_emit($data, YAML_UTF8_ENCODING, YAML_LN_BREAK);
24   }
25
26   /**
27    * {@inheritdoc}
28    */
29   public static function decode($raw) {
30     static $init;
31     if (!isset($init)) {
32       // We never want to unserialize !php/object.
33       ini_set('yaml.decode_php', 0);
34       $init = TRUE;
35     }
36     // yaml_parse() will error with an empty value.
37     if (!trim($raw)) {
38       return NULL;
39     }
40     // @todo Use ErrorExceptions when https://drupal.org/node/1247666 is in.
41     // yaml_parse() will throw errors instead of raising an exception. Until
42     // such time as Drupal supports native PHP ErrorExceptions as the error
43     // handler, we need to temporarily set the error handler as ::errorHandler()
44     // and then restore it after decoding has occurred. This allows us to turn
45     // parsing errors into a throwable exception.
46     // @see Drupal\Component\Serialization\Exception\InvalidDataTypeException
47     // @see http://php.net/manual/en/class.errorexception.php
48     set_error_handler([__CLASS__, 'errorHandler']);
49     $ndocs = 0;
50     $data = yaml_parse($raw, 0, $ndocs, [
51       YAML_BOOL_TAG => '\Drupal\Component\Serialization\YamlPecl::applyBooleanCallbacks',
52     ]);
53     restore_error_handler();
54     return $data;
55   }
56
57   /**
58    * Handles errors for \Drupal\Component\Serialization\YamlPecl::decode().
59    *
60    * @param int $severity
61    *   The severity level of the error.
62    * @param string $message
63    *   The error message to display.
64    *
65    * @see \Drupal\Component\Serialization\YamlPecl::decode()
66    */
67   public static function errorHandler($severity, $message) {
68     restore_error_handler();
69     throw new InvalidDataTypeException($message, $severity);
70   }
71
72   /**
73    * {@inheritdoc}
74    */
75   public static function getFileExtension() {
76     return 'yml';
77   }
78
79   /**
80    * Applies callbacks after parsing to ignore 1.1 style booleans.
81    *
82    * @param mixed $value
83    *   Value from YAML file.
84    * @param string $tag
85    *   Tag that triggered the callback.
86    * @param int $flags
87    *   Scalar entity style flags.
88    *
89    * @return string|bool
90    *   FALSE, false, TRUE and true are returned as booleans, everything else is
91    *   returned as a string.
92    */
93   public static function applyBooleanCallbacks($value, $tag, $flags) {
94     // YAML 1.1 spec dictates that 'Y', 'N', 'y' and 'n' are booleans. But, we
95     // want the 1.2 behavior, so we only consider 'false', 'FALSE', 'true' and
96     // 'TRUE' as booleans.
97     if (!in_array(strtolower($value), ['false', 'true'], TRUE)) {
98       return $value;
99     }
100     $map = [
101       'false' => FALSE,
102       'true' => TRUE,
103     ];
104     return $map[strtolower($value)];
105   }
106
107 }