PluginProbe
Polylang / trunk
Polylang vtrunk
3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 3.0.3 All 233 releases
← All changes | src/translatable-object.php +75 -41 3.8.4 → trunk View file →
@@ -125,11 +125,81 @@
125 125 'rewrite' => false,
126 126 '_pll' => true,
127 127 )
128 128 );
129 +
130 + $this->add_sanitization_hooks( $this->tax_language );
129 131 }
130 132
131 133 /**
134 + * Hooks sanitization for a Polylang taxonomy that stores serialized data in term descriptions.
135 + *
136 + * @since 3.8.10
137 + *
138 + * @param string $taxonomy Taxonomy name.
139 + * @return void
140 + *
141 + * @phpstan-param non-empty-string $taxonomy
142 + */
143 + protected function add_sanitization_hooks( string $taxonomy ): void {
144 + add_filter( "pre_{$taxonomy}_description", array( $this, 'sanitize_description' ), 0 );
145 + add_filter( "get_{$taxonomy}", array( $this, 'sanitize_term' ), 0 );
146 + }
147 +
148 + /**
149 + * Empties the description of a term hydrated from the database when it holds a disallowed serialized type.
150 + *
151 + * `get_{$taxonomy}` is fired by `get_term()`, whatever the sanitization context, and thus covers the
152 + * terms hydrated by `get_terms()` and `wp_get_object_terms()` too. Only the returned object is modified,
153 + * the stored value is left untouched.
154 + *
155 + * @since 3.8.10
156 + *
157 + * @param mixed $term Term object, may be anything another callback returned.
158 + * @return mixed The term, with a sanitized description.
159 + */
160 + public function sanitize_term( $term ) {
161 + if ( $term instanceof WP_Term && $this->has_disallowed_type( $term->description ) ) {
162 + $term->description = '';
163 + }
164 +
165 + return $term;
166 + }
167 +
168 + /**
169 + * Drops serialized values that contain a disallowed PHP type.
170 + *
171 + * @since 3.8.10
172 + *
173 + * @param mixed $description Term description.
174 + * @return string Empty string for a non-string value or when a disallowed type is found, unchanged otherwise.
175 + */
176 + public function sanitize_description( $description ) {
177 + if ( ! is_string( $description ) || '' === $description ) {
178 + return '';
179 + }
180 +
181 + return $this->has_disallowed_type( $description ) ? '' : $description;
182 + }
183 +
184 + /**
185 + * Tells if a serialized value contains a disallowed PHP type.
186 + *
187 + * The regex does not parse string payloads: a string value containing `{O:` or `";O:`
188 + * is treated as a disallowed type.
189 + *
190 + * Allowed serialized types: array, string, int, and bool.
191 + *
192 + * @since 3.8.10
193 + *
194 + * @param string $description Term description.
195 + * @return bool
196 + */
197 + private function has_disallowed_type( string $description ): bool {
198 + return 0 !== preg_match( '#(?:^|[;{])(?:[OCEdrR]:|N;)#', $description );
199 + }
200 +
201 + /**
132 202 * Returns the language taxonomy name.
133 203 *
134 204 * @since 3.4
135 205 *
@@ -175,9 +245,9 @@
175 245 * @return bool True when successfully assigned. False otherwise (or if the given language is already assigned to
176 246 * the object).
177 247 */
178 248 public function set_language( $id, $lang ) {
179 - $id = $this->sanitize_int_id( $id );
249 + $id = pll_sanitize_id( $id );
180 250
181 251 if ( empty( $id ) ) {
182 252 return false;
183 253 }
@@ -209,9 +279,9 @@
209 279 * @return PLL_Language|false A `PLL_Language` object. `false` if no language is associated to that object or if the
210 280 * ID is invalid.
211 281 */
212 282 public function get_language( $id ) {
213 - $id = $this->sanitize_int_id( $id );
283 + $id = pll_sanitize_id( $id );
214 284
215 285 if ( empty( $id ) ) {
216 286 return false;
217 287 }
@@ -234,9 +304,9 @@
234 304 * @param int $id Term ID.
235 305 * @return void
236 306 */
237 307 public function delete_language( $id ) {
238 - $id = $this->sanitize_int_id( $id );
308 + $id = pll_sanitize_id( $id );
239 309
240 310 if ( empty( $id ) ) {
241 311 return;
242 312 }
@@ -253,9 +323,9 @@
253 323 * @param string $taxonomy Taxonomy name.
254 324 * @return array<int,WP_Term> Array of terms with object ID as key.
255 325 */
256 326 protected function get_object_terms( array $object_ids, string $taxonomy ) {
257 - $object_ids = $this->sanitize_int_ids_list( $object_ids );
327 + $object_ids = pll_sanitize_ids( $object_ids );
258 328 if ( empty( $object_ids ) ) {
259 329 return array();
260 330 }
261 331
@@ -464,9 +534,9 @@
464 534 }
465 535
466 536 $object_ids = $this->query_objects_with_no_lang( $language_ids, $limit, $args );
467 537
468 - return array_values( $this->sanitize_int_ids_list( $object_ids ) );
538 + return array_values( pll_sanitize_ids( $object_ids ) );
469 539 }
470 540
471 541 /**
472 542 * Returns object IDs without language.
@@ -496,44 +566,8 @@
496 566 $object_ids = $this->get_raw_objects_with_no_lang( $language_ids, $limit, $args );
497 567 $this->set_to_cache( $key, $object_ids );
498 568
499 569 return $object_ids;
500 - }
501 -
502 - /**
503 - * Sanitizes an ID as positive integer.
504 - * Kind of similar to `absint()`, but rejects negative integers instead of making them positive.
505 - *
506 - * @since 3.2
507 - *
508 - * @param mixed $id A supposedly numeric ID.
509 - * @return int A positive integer. `0` for non numeric values and negative integers.
510 - *
511 - * @phpstan-return int<0,max>
512 - */
513 - public function sanitize_int_id( $id ) {
514 - return is_numeric( $id ) && $id >= 1 ? abs( (int) $id ) : 0;
515 - }
516 -
517 - /**
518 - * Sanitizes an array of IDs as positive integers.
519 - * `0` values are removed.
520 - *
521 - * @since 3.2
522 - *
523 - * @param mixed $ids An array of numeric IDs.
524 - * @return int[]
525 - *
526 - * @phpstan-return array<positive-int>
527 - */
528 - public function sanitize_int_ids_list( $ids ) {
529 - if ( empty( $ids ) || ! is_array( $ids ) ) {
530 - return array();
531 - }
532 -
533 - $ids = array_map( array( $this, 'sanitize_int_id' ), $ids );
534 -
535 - return array_filter( $ids );
536 570 }
537 571
538 572 /**
539 573 * Fetches the IDs of the objects without language.