Changeset 60771 for trunk/src/wp-includes/SimplePie/src/Sanitize.php
- Timestamp:
- 09/16/2025 10:45:37 PM (2 months ago)
- File:
-
- 1 edited
-
trunk/src/wp-includes/SimplePie/src/Sanitize.php (modified) (39 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/SimplePie/src/Sanitize.php
r59141 r60771 1 1 <?php 2 2 3 /** 4 * SimplePie 5 * 6 * A PHP-Based RSS and Atom Feed Framework. 7 * Takes the hard work out of managing a complete RSS/Atom solution. 8 * 9 * Copyright (c) 2004-2022, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without modification, are 13 * permitted provided that the following conditions are met: 14 * 15 * * Redistributions of source code must retain the above copyright notice, this list of 16 * conditions and the following disclaimer. 17 * 18 * * Redistributions in binary form must reproduce the above copyright notice, this list 19 * of conditions and the following disclaimer in the documentation and/or other materials 20 * provided with the distribution. 21 * 22 * * Neither the name of the SimplePie Team nor the names of its contributors may be used 23 * to endorse or promote products derived from this software without specific prior 24 * written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 27 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 28 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 29 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 33 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGE. 35 * 36 * @package SimplePie 37 * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue 38 * @author Ryan Parman 39 * @author Sam Sneddon 40 * @author Ryan McCue 41 * @link http://simplepie.org/ SimplePie 42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 43 */ 3 // SPDX-FileCopyrightText: 2004-2023 Ryan Parman, Sam Sneddon, Ryan McCue 4 // SPDX-License-Identifier: BSD-3-Clause 5 6 declare(strict_types=1); 44 7 45 8 namespace SimplePie; 46 9 10 use DOMDocument; 11 use DOMXPath; 47 12 use InvalidArgumentException; 13 use Psr\Http\Client\ClientInterface; 14 use Psr\Http\Message\RequestFactoryInterface; 15 use Psr\Http\Message\UriFactoryInterface; 48 16 use SimplePie\Cache\Base; 49 17 use SimplePie\Cache\BaseDataCache; … … 51 19 use SimplePie\Cache\DataCache; 52 20 use SimplePie\Cache\NameFilter; 21 use SimplePie\HTTP\Client; 22 use SimplePie\HTTP\ClientException; 23 use SimplePie\HTTP\FileClient; 24 use SimplePie\HTTP\Psr18Client; 53 25 54 26 /** … … 58 30 * This class can be overloaded with {@see \SimplePie\SimplePie::set_sanitize_class()} 59 31 * 60 * @package SimplePie61 32 * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags 62 33 */ … … 64 35 { 65 36 // Private vars 66 public $base; 37 /** @var string */ 38 public $base = ''; 67 39 68 40 // Options 41 /** @var bool */ 69 42 public $remove_div = true; 43 /** @var string */ 70 44 public $image_handler = ''; 45 /** @var string[] */ 71 46 public $strip_htmltags = ['base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style']; 47 /** @var bool */ 72 48 public $encode_instead_of_strip = false; 49 /** @var string[] */ 73 50 public $strip_attributes = ['bgsound', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc']; 51 /** @var string[] */ 74 52 public $rename_attributes = []; 53 /** @var array<string, array<string, string>> */ 75 54 public $add_attributes = ['audio' => ['preload' => 'none'], 'iframe' => ['sandbox' => 'allow-scripts allow-same-origin'], 'video' => ['preload' => 'none']]; 55 /** @var bool */ 76 56 public $strip_comments = false; 57 /** @var string */ 77 58 public $output_encoding = 'UTF-8'; 59 /** @var bool */ 78 60 public $enable_cache = true; 61 /** @var string */ 79 62 public $cache_location = './cache'; 63 /** @var string&(callable(string): string) */ 80 64 public $cache_name_function = 'md5'; 81 65 … … 84 68 */ 85 69 private $cache_namefilter; 70 /** @var int */ 86 71 public $timeout = 10; 72 /** @var string */ 87 73 public $useragent = ''; 74 /** @var bool */ 88 75 public $force_fsockopen = false; 89 public $replace_url_attributes = null; 76 /** @var array<string, string|string[]> */ 77 public $replace_url_attributes = []; 78 /** 79 * @var array<int, mixed> Custom curl options 80 * @see SimplePie::set_curl_options() 81 */ 82 private $curl_options = []; 83 84 /** @var Registry */ 90 85 public $registry; 91 86 … … 105 100 * Array is a tree split at DNS levels. Example: 106 101 * array('biz' => true, 'com' => array('example' => true), 'net' => array('example' => array('www' => true))) 102 * @var true|array<string, true|array<string, true|array<string, array<string, true|array<string, true|array<string, true>>>>>> 107 103 */ 108 104 public $https_domains = []; 105 106 /** 107 * @var Client|null 108 */ 109 private $http_client = null; 109 110 110 111 public function __construct() … … 114 115 } 115 116 116 public function remove_div($enable = true) 117 /** 118 * @return void 119 */ 120 public function remove_div(bool $enable = true) 117 121 { 118 122 $this->remove_div = (bool) $enable; 119 123 } 120 124 125 /** 126 * @param string|false $page 127 * @return void 128 */ 121 129 public function set_image_handler($page = false) 122 130 { … … 124 132 $this->image_handler = (string) $page; 125 133 } else { 126 $this->image_handler = false; 127 } 128 } 129 130 public function set_registry(\SimplePie\Registry $registry)/* : void */ 134 $this->image_handler = ''; 135 } 136 } 137 138 /** 139 * @return void 140 */ 141 public function set_registry(\SimplePie\Registry $registry) 131 142 { 132 143 $this->registry = $registry; 133 144 } 134 145 135 public function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie\Cache', ?DataCache $cache = null) 136 { 137 if (isset($enable_cache)) { 138 $this->enable_cache = (bool) $enable_cache; 139 } 146 /** 147 * @param (string&(callable(string): string))|NameFilter $cache_name_function 148 * @param class-string<Cache> $cache_class 149 * @return void 150 */ 151 public function pass_cache_data(bool $enable_cache = true, string $cache_location = './cache', $cache_name_function = 'md5', string $cache_class = Cache::class, ?DataCache $cache = null) 152 { 153 $this->enable_cache = $enable_cache; 140 154 141 155 if ($cache_location) { 142 $this->cache_location = (string) $cache_location; 143 } 144 145 if (!is_string($cache_name_function) && !is_object($cache_name_function) && !$cache_name_function instanceof NameFilter) { 156 $this->cache_location = $cache_location; 157 } 158 159 // @phpstan-ignore-next-line Enforce PHPDoc type. 160 if (!is_string($cache_name_function) && !$cache_name_function instanceof NameFilter) { 146 161 throw new InvalidArgumentException(sprintf( 147 162 '%s(): Argument #3 ($cache_name_function) must be of type %s', … … 154 169 if (is_string($cache_name_function)) { 155 170 // trigger_error(sprintf('Providing $cache_name_function as string in "%s()" is deprecated since SimplePie 1.8.0, provide as "%s" instead.', __METHOD__, NameFilter::class), \E_USER_DEPRECATED); 156 $this->cache_name_function = (string)$cache_name_function;171 $this->cache_name_function = $cache_name_function; 157 172 158 173 $cache_name_function = new CallableNameFilter($cache_name_function); … … 166 181 } 167 182 168 public function pass_file_data($file_class = 'SimplePie\File', $timeout = 10, $useragent = '', $force_fsockopen = false) 169 { 183 /** 184 * Set a PSR-18 client and PSR-17 factories 185 * 186 * Allows you to use your own HTTP client implementations. 187 */ 188 final public function set_http_client( 189 ClientInterface $http_client, 190 RequestFactoryInterface $request_factory, 191 UriFactoryInterface $uri_factory 192 ): void { 193 $this->http_client = new Psr18Client($http_client, $request_factory, $uri_factory); 194 } 195 196 /** 197 * @deprecated since SimplePie 1.9.0, use \SimplePie\Sanitize::set_http_client() instead. 198 * @param class-string<File> $file_class 199 * @param array<int, mixed> $curl_options 200 * @return void 201 */ 202 public function pass_file_data(string $file_class = File::class, int $timeout = 10, string $useragent = '', bool $force_fsockopen = false, array $curl_options = []) 203 { 204 // trigger_error(sprintf('SimplePie\Sanitize::pass_file_data() is deprecated since SimplePie 1.9.0, please use "SimplePie\Sanitize::set_http_client()" instead.'), \E_USER_DEPRECATED); 170 205 if ($timeout) { 171 $this->timeout = (string)$timeout;206 $this->timeout = $timeout; 172 207 } 173 208 174 209 if ($useragent) { 175 $this->useragent = (string)$useragent;210 $this->useragent = $useragent; 176 211 } 177 212 178 213 if ($force_fsockopen) { 179 $this->force_fsockopen = (string) $force_fsockopen; 180 } 181 } 182 214 $this->force_fsockopen = $force_fsockopen; 215 } 216 217 $this->curl_options = $curl_options; 218 // Invalidate the registered client. 219 $this->http_client = null; 220 } 221 222 /** 223 * @param string[]|string|false $tags Set a list of tags to strip, or set empty string to use default tags, or false to strip nothing. 224 * @return void 225 */ 183 226 public function strip_htmltags($tags = ['base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style']) 184 227 { … … 190 233 } 191 234 } else { 192 $this->strip_htmltags = false; 193 } 194 } 195 196 public function encode_instead_of_strip($encode = false) 197 { 198 $this->encode_instead_of_strip = (bool) $encode; 199 } 200 235 $this->strip_htmltags = []; 236 } 237 } 238 239 /** 240 * @return void 241 */ 242 public function encode_instead_of_strip(bool $encode = false) 243 { 244 $this->encode_instead_of_strip = $encode; 245 } 246 247 /** 248 * @param string[]|string $attribs 249 * @return void 250 */ 201 251 public function rename_attributes($attribs = []) 202 252 { … … 208 258 } 209 259 } else { 210 $this->rename_attributes = false; 211 } 212 } 213 260 $this->rename_attributes = []; 261 } 262 } 263 264 /** 265 * @param string[]|string $attribs 266 * @return void 267 */ 214 268 public function strip_attributes($attribs = ['bgsound', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc']) 215 269 { … … 221 275 } 222 276 } else { 223 $this->strip_attributes = false; 224 } 225 } 226 227 public function add_attributes($attribs = ['audio' => ['preload' => 'none'], 'iframe' => ['sandbox' => 'allow-scripts allow-same-origin'], 'video' => ['preload' => 'none']]) 228 { 229 if ($attribs) { 230 if (is_array($attribs)) { 231 $this->add_attributes = $attribs; 232 } else { 233 $this->add_attributes = explode(',', $attribs); 234 } 235 } else { 236 $this->add_attributes = false; 237 } 238 } 239 240 public function strip_comments($strip = false) 241 { 242 $this->strip_comments = (bool) $strip; 243 } 244 245 public function set_output_encoding($encoding = 'UTF-8') 246 { 247 $this->output_encoding = (string) $encoding; 277 $this->strip_attributes = []; 278 } 279 } 280 281 /** 282 * @param array<string, array<string, string>> $attribs 283 * @return void 284 */ 285 public function add_attributes(array $attribs = ['audio' => ['preload' => 'none'], 'iframe' => ['sandbox' => 'allow-scripts allow-same-origin'], 'video' => ['preload' => 'none']]) 286 { 287 $this->add_attributes = $attribs; 288 } 289 290 /** 291 * @return void 292 */ 293 public function strip_comments(bool $strip = false) 294 { 295 $this->strip_comments = $strip; 296 } 297 298 /** 299 * @return void 300 */ 301 public function set_output_encoding(string $encoding = 'UTF-8') 302 { 303 $this->output_encoding = $encoding; 248 304 } 249 305 … … 257 313 * 258 314 * @since 1.0 259 * @param array|null $element_attribute Element/attribute key/value pairs, null for default 260 */ 261 public function set_url_replacements($element_attribute = null) 315 * @param array<string, string|string[]>|null $element_attribute Element/attribute key/value pairs, null for default 316 * @return void 317 */ 318 public function set_url_replacements(?array $element_attribute = null) 262 319 { 263 320 if ($element_attribute === null) { … … 283 340 ]; 284 341 } 285 $this->replace_url_attributes = (array)$element_attribute;342 $this->replace_url_attributes = $element_attribute; 286 343 } 287 344 … … 290 347 * @see \SimplePie\Misc::https_url() 291 348 * Example array('biz', 'example.com', 'example.org', 'www.example.net'); 292 */ 293 public function set_https_domains($domains) 349 * 350 * @param string[] $domains list of domain names ['biz', 'example.com', 'example.org', 'www.example.net'] 351 * 352 * @return void 353 */ 354 public function set_https_domains(array $domains) 294 355 { 295 356 $this->https_domains = []; … … 297 358 $domain = trim($domain, ". \t\n\r\0\x0B"); 298 359 $segments = array_reverse(explode('.', $domain)); 360 /** @var true|array<string, true|array<string, true|array<string, array<string, true|array<string, true|array<string, true>>>>>> */ // Needed for PHPStan. 299 361 $node = &$this->https_domains; 300 362 foreach ($segments as $segment) {//Build a tree … … 313 375 /** 314 376 * Check if the domain is in the list of forced HTTPS. 315 */ 316 protected function is_https_domain($domain) 377 * 378 * @return bool 379 */ 380 protected function is_https_domain(string $domain) 317 381 { 318 382 $domain = trim($domain, '. '); … … 331 395 /** 332 396 * Force HTTPS for selected Web sites. 333 */ 334 public function https_url($url) 335 { 336 return (strtolower(substr($url, 0, 7)) === 'http://') && 337 $this->is_https_domain(parse_url($url, PHP_URL_HOST)) ? 338 substr_replace($url, 's', 4, 0) : //Add the 's' to HTTPS 339 $url; 340 } 341 342 public function sanitize($data, $type, $base = '') 397 * 398 * @return string 399 */ 400 public function https_url(string $url) 401 { 402 return ( 403 strtolower(substr($url, 0, 7)) === 'http://' 404 && ($parsed = parse_url($url, PHP_URL_HOST)) !== false // Malformed URL 405 && $parsed !== null // Missing host 406 && $this->is_https_domain($parsed) // Should be forced? 407 ) ? substr_replace($url, 's', 4, 0) // Add the 's' to HTTPS 408 : $url; 409 } 410 411 /** 412 * @param int-mask-of<SimplePie::CONSTRUCT_*> $type 413 * @param string $base 414 * @return string Sanitized data; false if output encoding is changed to something other than UTF-8 and conversion fails 415 */ 416 public function sanitize(string $data, int $type, string $base = '') 343 417 { 344 418 $data = trim($data); … … 363 437 $document->encoding = 'UTF-8'; 364 438 439 // PHPStan seems to have trouble resolving int-mask because bitwise 440 // operators are used when operators are used when passing this parameter. 441 // https://github.com/phpstan/phpstan/issues/9384 442 /** @var int-mask-of<SimplePie::CONSTRUCT_*> $type */ 365 443 $data = $this->preprocess($data, $type); 366 444 367 set_error_handler([ 'SimplePie\Misc', 'silence_errors']);445 set_error_handler([Misc::class, 'silence_errors']); 368 446 $document->loadHTML($data); 369 447 restore_error_handler(); … … 373 451 // Strip comments 374 452 if ($this->strip_comments) { 453 /** @var \DOMNodeList<\DOMComment> */ 375 454 $comments = $xpath->query('//comment()'); 376 455 377 456 foreach ($comments as $comment) { 378 $comment->parentNode->removeChild($comment); 457 $parentNode = $comment->parentNode; 458 assert($parentNode !== null, 'For PHPStan, comment must have a parent'); 459 $parentNode->removeChild($comment); 379 460 } 380 461 } … … 382 463 // Strip out HTML tags and attributes that might cause various security problems. 383 464 // Based on recommendations by Mark Pilgrim at: 384 // http ://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely465 // https://web.archive.org/web/20110902041826/http://diveintomark.org:80/archives/2003/06/12/how_to_consume_rss_safely 385 466 if ($this->strip_htmltags) { 386 467 foreach ($this->strip_htmltags as $tag) { … … 414 495 415 496 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags. 416 if ( isset($this->image_handler) && ((string) $this->image_handler)!== '' && $this->enable_cache) {497 if ($this->image_handler !== '' && $this->enable_cache) { 417 498 $images = $document->getElementsByTagName('img'); 418 499 … … 425 506 $img->setAttribute('src', $this->image_handler . $image_url); 426 507 } else { 427 $file = $this->registry->create(File::class, [$img->getAttribute('src'), $this->timeout, 5, ['X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']], $this->useragent, $this->force_fsockopen]); 428 $headers = $file->headers; 429 430 if ($file->success && ($file->method & \SimplePie\SimplePie::FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300))) { 431 if ($cache->set_data($image_url, ['headers' => $file->headers, 'body' => $file->body], $this->cache_duration)) { 508 try { 509 $file = $this->get_http_client()->request( 510 Client::METHOD_GET, 511 $img->getAttribute('src'), 512 ['X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']] 513 ); 514 } catch (ClientException $th) { 515 continue; 516 } 517 518 if ((!Misc::is_remote_uri($file->get_final_requested_uri()) || ($file->get_status_code() === 200 || $file->get_status_code() > 206 && $file->get_status_code() < 300))) { 519 if ($cache->set_data($image_url, ['headers' => $file->get_headers(), 'body' => $file->get_body_content()], $this->cache_duration)) { 432 520 $img->setAttribute('src', $this->image_handler . $image_url); 433 521 } else { … … 441 529 442 530 // Get content node 443 $div = $document->getElementsByTagName('body')->item(0)->firstChild; 531 $div = null; 532 if (($item = $document->getElementsByTagName('body')->item(0)) !== null) { 533 $div = $item->firstChild; 534 } 444 535 // Finally, convert to a HTML string 445 $data = trim( $document->saveHTML($div));536 $data = trim((string) $document->saveHTML($div)); 446 537 447 538 if ($this->remove_div) { 448 539 $data = preg_replace('/^<div' . \SimplePie\SimplePie::PCRE_XML_ATTRIBUTE . '>/', '', $data); 449 $data = preg_replace('/<\/div>$/', '', $data); 540 // Cast for PHPStan, it is unable to validate a non-literal regex above. 541 $data = preg_replace('/<\/div>$/', '', (string) $data); 450 542 } else { 451 543 $data = preg_replace('/^<div' . \SimplePie\SimplePie::PCRE_XML_ATTRIBUTE . '>/', '<div>', $data); 452 544 } 453 545 454 $data = str_replace('</source>', '', $data); 546 // Cast for PHPStan, it is unable to validate a non-literal regex above. 547 $data = str_replace('</source>', '', (string) $data); 455 548 } 456 549 … … 467 560 468 561 if ($this->output_encoding !== 'UTF-8') { 562 // This really returns string|false but changing encoding is uncommon and we are going to deprecate it, so let’s just lie to PHPStan in the interest of cleaner annotations. 563 /** @var string */ 469 564 $data = $this->registry->call(Misc::class, 'change_encoding', [$data, 'UTF-8', $this->output_encoding]); 470 565 } … … 473 568 } 474 569 475 protected function preprocess($html, $type) 570 /** 571 * @param int-mask-of<SimplePie::CONSTRUCT_*> $type 572 * @return string 573 */ 574 protected function preprocess(string $html, int $type) 476 575 { 477 576 $ret = ''; … … 494 593 } 495 594 496 public function replace_urls($document, $tag, $attributes) 595 /** 596 * @param array<string>|string $attributes 597 * @return void 598 */ 599 public function replace_urls(DOMDocument $document, string $tag, $attributes) 497 600 { 498 601 if (!is_array($attributes)) { … … 516 619 } 517 620 518 public function do_strip_htmltags($match) 621 /** 622 * @param array<int, string> $match 623 * @return string 624 */ 625 public function do_strip_htmltags(array $match) 519 626 { 520 627 if ($this->encode_instead_of_strip) { … … 533 640 } 534 641 535 protected function strip_tag($tag, $document, $xpath, $type) 642 /** 643 * @param int-mask-of<SimplePie::CONSTRUCT_*> $type 644 * @return void 645 */ 646 protected function strip_tag(string $tag, DOMDocument $document, DOMXPath $xpath, int $type) 536 647 { 537 648 $elements = $xpath->query('body//' . $tag); 649 650 if ($elements === false) { 651 throw new \SimplePie\Exception(sprintf( 652 '%s(): Possibly malformed expression, check argument #1 ($tag)', 653 __METHOD__ 654 ), 1); 655 } 656 538 657 if ($this->encode_instead_of_strip) { 539 658 foreach ($elements as $element) { … … 543 662 if (!in_array($tag, ['script', 'style'])) { 544 663 $text = '<' . $tag; 545 if ($element-> hasAttributes()) {664 if ($element->attributes !== null) { 546 665 $attrs = []; 547 666 foreach ($element->attributes as $name => $attr) { … … 569 688 $number = $element->childNodes->length; 570 689 for ($i = $number; $i > 0; $i--) { 571 $child = $element->childNodes->item(0); 572 $fragment->appendChild($child); 690 if (($child = $element->childNodes->item(0)) !== null) { 691 $fragment->appendChild($child); 692 } 573 693 } 574 694 … … 577 697 } 578 698 579 $element->parentNode->replaceChild($fragment, $element); 699 if (($parentNode = $element->parentNode) !== null) { 700 $parentNode->replaceChild($fragment, $element); 701 } 580 702 } 581 703 … … 583 705 } elseif (in_array($tag, ['script', 'style'])) { 584 706 foreach ($elements as $element) { 585 $element->parentNode->removeChild($element); 707 if (($parentNode = $element->parentNode) !== null) { 708 $parentNode->removeChild($element); 709 } 586 710 } 587 711 … … 592 716 $number = $element->childNodes->length; 593 717 for ($i = $number; $i > 0; $i--) { 594 $child = $element->childNodes->item(0); 595 $fragment->appendChild($child); 596 } 597 598 $element->parentNode->replaceChild($fragment, $element); 599 } 600 } 601 } 602 603 protected function strip_attr($attrib, $xpath) 718 if (($child = $element->childNodes->item(0)) !== null) { 719 $fragment->appendChild($child); 720 } 721 } 722 723 if (($parentNode = $element->parentNode) !== null) { 724 $parentNode->replaceChild($fragment, $element); 725 } 726 } 727 } 728 } 729 730 /** 731 * @return void 732 */ 733 protected function strip_attr(string $attrib, DOMXPath $xpath) 604 734 { 605 735 $elements = $xpath->query('//*[@' . $attrib . ']'); 606 736 737 if ($elements === false) { 738 throw new \SimplePie\Exception(sprintf( 739 '%s(): Possibly malformed expression, check argument #1 ($attrib)', 740 __METHOD__ 741 ), 1); 742 } 743 744 /** @var \DOMElement $element */ 607 745 foreach ($elements as $element) { 608 746 $element->removeAttribute($attrib); … … 610 748 } 611 749 612 protected function rename_attr($attrib, $xpath) 750 /** 751 * @return void 752 */ 753 protected function rename_attr(string $attrib, DOMXPath $xpath) 613 754 { 614 755 $elements = $xpath->query('//*[@' . $attrib . ']'); 615 756 757 if ($elements === false) { 758 throw new \SimplePie\Exception(sprintf( 759 '%s(): Possibly malformed expression, check argument #1 ($attrib)', 760 __METHOD__ 761 ), 1); 762 } 763 764 /** @var \DOMElement $element */ 616 765 foreach ($elements as $element) { 617 766 $element->setAttribute('data-sanitized-' . $attrib, $element->getAttribute($attrib)); … … 620 769 } 621 770 622 protected function add_attr($tag, $valuePairs, $document) 771 /** 772 * @param array<string, string> $valuePairs 773 * @return void 774 */ 775 protected function add_attr(string $tag, array $valuePairs, DOMDocument $document) 623 776 { 624 777 $elements = $document->getElementsByTagName($tag); 778 /** @var \DOMElement $element */ 625 779 foreach ($elements as $element) { 626 780 foreach ($valuePairs as $attrib => $value) { … … 637 791 * @return DataCache 638 792 */ 639 private function get_cache( $image_url = '')793 private function get_cache(string $image_url = ''): DataCache 640 794 { 641 795 if ($this->cache === null) { … … 652 806 return $this->cache; 653 807 } 808 809 /** 810 * Get a HTTP client 811 */ 812 private function get_http_client(): Client 813 { 814 if ($this->http_client === null) { 815 $this->http_client = new FileClient( 816 $this->registry, 817 [ 818 'timeout' => $this->timeout, 819 'redirects' => 5, 820 'useragent' => $this->useragent, 821 'force_fsockopen' => $this->force_fsockopen, 822 'curl_options' => $this->curl_options, 823 ] 824 ); 825 } 826 827 return $this->http_client; 828 } 654 829 } 655 830
Note: See TracChangeset
for help on using the changeset viewer.