PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / trunk
Yoast SEO – Advanced SEO with real-time guidance and built-in AI vtrunk
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
← All changes | inc/sitemaps/class-sitemap-cache-data.php +26 -8 18.9 → trunk View file →
@@ -27,8 +27,10 @@
27 27 /**
28 28 * Set the sitemap XML data
29 29 *
30 30 * @param string $sitemap XML Content of the sitemap.
31 + *
32 + * @return void
31 33 */
32 34 public function set_sitemap( $sitemap ) {
33 35
34 36 if ( ! is_string( $sitemap ) ) {
@@ -171,16 +173,31 @@
171 173
172 174 /**
173 175 * Constructs the object.
174 176 *
175 - * {@internal The magic methods take precedence over the Serializable interface.
176 - * This means that in practice, this method will now only be called on PHP < 7.4.
177 - * For PHP 7.4 and higher, the magic methods will be used instead.}
177 + * {@internal Unlike `serialize()` above, this method is NOT superseded by its magic counterpart
178 + * on PHP 7.4 and higher, so it is live code on every supported PHP version. PHP selects the
179 + * handler based on the *format* of the payload being read, not on the PHP version: `O:`-format
180 + * payloads are routed to `__unserialize()`, whereas `C:`-format payloads are dispatched here,
181 + * because this class implements `Serializable`. Verified on PHP 7.4 through 8.3.
182 + * There is no call to this method anywhere in the codebase; the engine invokes it.}
178 183 *
184 + * {@internal `$data` must be treated as untrusted. `C:`-format payloads survive WordPress
185 + * unaltered on the way into the database, because `is_serialized()` has no case for `C` and
186 + * `maybe_serialize()` therefore stores such a string verbatim rather than escaping it. Any code
187 + * path that unserializes third-party data can consequently reach this method with a crafted
188 + * payload.
189 + * The nested call is restricted with `allowed_classes => false` for that reason: a legitimate
190 + * payload only ever contains the two strings produced by `__serialize()`, so instantiating a
191 + * class here is never valid, and permitting it turns this method into an object-injection sink
192 + * that ends in an arbitrary `__destruct()`. Do not relax that restriction.}
193 + *
179 194 * {@internal The Serializable interface is being phased out, in favour of the magic methods.
180 - * This method should be deprecated and removed and the class should no longer
181 - * implement the `Serializable` interface.
182 - * This change, however, can't be made until the minimum PHP version goes up to PHP 7.4 or higher.}
195 + * This method should be deprecated and removed and the class should no longer implement the
196 + * `Serializable` interface. The minimum supported PHP version has since risen to 7.4, so that is
197 + * now possible, but it is deliberately left as a separate change: dropping the interface alters
198 + * how sitemap caches originally written on PHP < 7.4 are handled, as PHP then returns an empty
199 + * instance for those payloads instead of a populated one.}
183 200 *
184 201 * @link http://php.net/manual/en/serializable.unserialize.php
185 202 * @link https://wiki.php.net/rfc/phase_out_serializable
186 203 *
@@ -185,14 +202,15 @@
185 202 * @link https://wiki.php.net/rfc/phase_out_serializable
186 203 *
187 204 * @since 5.1.0
188 205 *
189 - * @param string $data The string representation of the object in C or O-format.
206 + * @param string $data Untrusted serialized representation of the data array, as carried in the
207 + * body of a `C:`-format payload naming this class.
190 208 *
191 209 * @return void
192 210 */
193 211 public function unserialize( $data ) {
194 212
195 - $data = unserialize( $data );
213 + $data = unserialize( $data, [ 'allowed_classes' => false ] );
196 214 $this->__unserialize( $data );
197 215 }
198 216 }