Version Description
Requires WordPress >
Download this release
Release Info
Developer | shazahm1@hotmail.com |
Plugin | Easy Table of Contents |
Version | 2.0.9 |
Comparing to | |
See all releases |
Code changes from version 2.0.8 to 2.0.9
- README.txt +12 -1
- easy-table-of-contents.php +11 -11
- includes/class.post.php +9 -2
- includes/inc.plugin-compatibility.php +16 -0
- includes/vendor/ultimate-web-scraper/crc32_stream.php +3 -3
- includes/vendor/ultimate-web-scraper/deflate_stream.php +6 -6
- includes/vendor/ultimate-web-scraper/http.php +75 -9
- includes/vendor/ultimate-web-scraper/tag_filter.php +83 -83
- includes/vendor/ultimate-web-scraper/websocket.php +6 -6
README.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: table of contents, toc
|
|
5 |
Requires at least: 5.2
|
6 |
Tested up to: 5.4
|
7 |
Requires PHP: 5.6.20
|
8 |
-
Stable tag: 2.0.
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -89,6 +89,14 @@ Easy Table Contents is a fork of the excellent [Table of Contents Plus](https://
|
|
89 |
|
90 |
== Changelog ==
|
91 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
= 2.0.8 04/03/2020 =
|
93 |
* TWEAK: Convert `<br />` tags in headings to a space.
|
94 |
* TWEAK: Add additional widget classes.
|
@@ -388,3 +396,6 @@ Requires WordPress >= 5.0 and PHP version >= 5.6.20 (>= 7.1 is recommended).
|
|
388 |
|
389 |
= 2.0.8 =
|
390 |
Requires WordPress >= 5.0 and PHP version >= 5.6.20 (>= 7.1 is recommended).
|
|
|
|
|
|
5 |
Requires at least: 5.2
|
6 |
Tested up to: 5.4
|
7 |
Requires PHP: 5.6.20
|
8 |
+
Stable tag: 2.0.9
|
9 |
License: GPLv2 or later
|
10 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
89 |
|
90 |
== Changelog ==
|
91 |
|
92 |
+
= 2.0.9 04/08/2020 =
|
93 |
+
* TWEAK: AMP/Caching plugins seems to break anchors with colons and periods even though they are valid characters for the id attribute in HTML5.
|
94 |
+
* TWEAK: Replace multiple underscores with a single underscore.
|
95 |
+
* DEV: Update the UWS library which fixes the deprecation notice for PHP 7.4.
|
96 |
+
* DEV: Add phpcs.xml.dist.
|
97 |
+
* DEV: Strict type checks.
|
98 |
+
* DEV: Inline doc updates.
|
99 |
+
|
100 |
= 2.0.8 04/03/2020 =
|
101 |
* TWEAK: Convert `<br />` tags in headings to a space.
|
102 |
* TWEAK: Add additional widget classes.
|
396 |
|
397 |
= 2.0.8 =
|
398 |
Requires WordPress >= 5.0 and PHP version >= 5.6.20 (>= 7.1 is recommended).
|
399 |
+
|
400 |
+
= 2.0.9 =
|
401 |
+
Requires WordPress >= 5.0 and PHP version >= 5.6.20 (>= 7.1 is recommended).
|
easy-table-of-contents.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Easy Table of Contents
|
4 |
* Plugin URI: http://connections-pro.com/
|
5 |
* Description: Adds a user friendly and fully automatic way to create and display a table of contents generated from the page content.
|
6 |
-
* Version: 2.0.
|
7 |
* Author: Steven A. Zahm
|
8 |
* Author URI: http://connections-pro.com/
|
9 |
* Text Domain: easy-table-of-contents
|
@@ -26,7 +26,7 @@
|
|
26 |
* @package Easy Table of Contents
|
27 |
* @category Plugin
|
28 |
* @author Steven A. Zahm
|
29 |
-
* @version 2.0.
|
30 |
*/
|
31 |
|
32 |
use function Easy_Plugins\Table_Of_Contents\String\mb_find_replace;
|
@@ -47,7 +47,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
|
|
47 |
* @since 1.0
|
48 |
* @var string
|
49 |
*/
|
50 |
-
const VERSION = '2.0.
|
51 |
|
52 |
/**
|
53 |
* Stores the instance of this class.
|
@@ -250,7 +250,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
|
|
250 |
|
251 |
if ( ezTOC_Option::get( 'show_heading_text' ) && ezTOC_Option::get( 'visibility' ) ) {
|
252 |
|
253 |
-
$width = ezTOC_Option::get( 'width' )
|
254 |
|
255 |
$js_vars['visibility_hide_by_default'] = ezTOC_Option::get( 'visibility_hide_by_default' ) ? true : false;
|
256 |
|
@@ -289,20 +289,20 @@ if ( ! class_exists( 'ezTOC' ) ) {
|
|
289 |
$css .= 'div#ez-toc-container p.ez-toc-title {font-weight: ' . ezTOC_Option::get( 'title_font_weight', 500 ) . ';}';
|
290 |
$css .= 'div#ez-toc-container ul li {font-size: ' . ezTOC_Option::get( 'font_size' ) . ezTOC_Option::get( 'font_size_units' ) . ';}';
|
291 |
|
292 |
-
if ( ezTOC_Option::get( 'theme' )
|
293 |
|
294 |
$css .= 'div#ez-toc-container {';
|
295 |
|
296 |
-
if ( ezTOC_Option::get( 'theme' )
|
297 |
|
298 |
$css .= 'background: ' . ezTOC_Option::get( 'custom_background_colour' ) . ';border: 1px solid ' . ezTOC_Option::get( 'custom_border_colour' ) . ';';
|
299 |
}
|
300 |
|
301 |
-
if ( 'auto'
|
302 |
|
303 |
$css .= 'width: ';
|
304 |
|
305 |
-
if ( 'custom'
|
306 |
|
307 |
$css .= ezTOC_Option::get( 'width' );
|
308 |
|
@@ -317,7 +317,7 @@ if ( ! class_exists( 'ezTOC' ) ) {
|
|
317 |
$css .= '}';
|
318 |
}
|
319 |
|
320 |
-
if ( 'custom'
|
321 |
|
322 |
$css .= 'div#ez-toc-container p.ez-toc-title {color: ' . ezTOC_Option::get( 'custom_title_colour' ) . ';}';
|
323 |
//$css .= 'div#ez-toc-container p.ez-toc-title a,div#ez-toc-container ul.ez-toc-list a {color: ' . ezTOC_Option::get( 'custom_link_colour' ) . ';}';
|
@@ -397,8 +397,8 @@ if ( ! class_exists( 'ezTOC' ) ) {
|
|
397 |
|
398 |
$type = get_post_type( $post->ID );
|
399 |
|
400 |
-
$enabled = in_array( $type, ezTOC_Option::get( 'enabled_post_types', array() ) );
|
401 |
-
$insert = in_array( $type, ezTOC_Option::get( 'auto_insert_post_types', array() ) );
|
402 |
|
403 |
if ( $insert || $enabled ) {
|
404 |
|
3 |
* Plugin Name: Easy Table of Contents
|
4 |
* Plugin URI: http://connections-pro.com/
|
5 |
* Description: Adds a user friendly and fully automatic way to create and display a table of contents generated from the page content.
|
6 |
+
* Version: 2.0.9
|
7 |
* Author: Steven A. Zahm
|
8 |
* Author URI: http://connections-pro.com/
|
9 |
* Text Domain: easy-table-of-contents
|
26 |
* @package Easy Table of Contents
|
27 |
* @category Plugin
|
28 |
* @author Steven A. Zahm
|
29 |
+
* @version 2.0.9
|
30 |
*/
|
31 |
|
32 |
use function Easy_Plugins\Table_Of_Contents\String\mb_find_replace;
|
47 |
* @since 1.0
|
48 |
* @var string
|
49 |
*/
|
50 |
+
const VERSION = '2.0.9';
|
51 |
|
52 |
/**
|
53 |
* Stores the instance of this class.
|
250 |
|
251 |
if ( ezTOC_Option::get( 'show_heading_text' ) && ezTOC_Option::get( 'visibility' ) ) {
|
252 |
|
253 |
+
$width = ezTOC_Option::get( 'width' ) !== 'custom' ? ezTOC_Option::get( 'width' ) : ezTOC_Option::get( 'width_custom' ) . ezTOC_Option::get( 'width_custom_units' );
|
254 |
|
255 |
$js_vars['visibility_hide_by_default'] = ezTOC_Option::get( 'visibility_hide_by_default' ) ? true : false;
|
256 |
|
289 |
$css .= 'div#ez-toc-container p.ez-toc-title {font-weight: ' . ezTOC_Option::get( 'title_font_weight', 500 ) . ';}';
|
290 |
$css .= 'div#ez-toc-container ul li {font-size: ' . ezTOC_Option::get( 'font_size' ) . ezTOC_Option::get( 'font_size_units' ) . ';}';
|
291 |
|
292 |
+
if ( ezTOC_Option::get( 'theme' ) === 'custom' || ezTOC_Option::get( 'width' ) != 'auto' ) {
|
293 |
|
294 |
$css .= 'div#ez-toc-container {';
|
295 |
|
296 |
+
if ( ezTOC_Option::get( 'theme' ) === 'custom' ) {
|
297 |
|
298 |
$css .= 'background: ' . ezTOC_Option::get( 'custom_background_colour' ) . ';border: 1px solid ' . ezTOC_Option::get( 'custom_border_colour' ) . ';';
|
299 |
}
|
300 |
|
301 |
+
if ( 'auto' !== ezTOC_Option::get( 'width' ) ) {
|
302 |
|
303 |
$css .= 'width: ';
|
304 |
|
305 |
+
if ( 'custom' !== ezTOC_Option::get( 'width' ) ) {
|
306 |
|
307 |
$css .= ezTOC_Option::get( 'width' );
|
308 |
|
317 |
$css .= '}';
|
318 |
}
|
319 |
|
320 |
+
if ( 'custom' === ezTOC_Option::get( 'theme' ) ) {
|
321 |
|
322 |
$css .= 'div#ez-toc-container p.ez-toc-title {color: ' . ezTOC_Option::get( 'custom_title_colour' ) . ';}';
|
323 |
//$css .= 'div#ez-toc-container p.ez-toc-title a,div#ez-toc-container ul.ez-toc-list a {color: ' . ezTOC_Option::get( 'custom_link_colour' ) . ';}';
|
397 |
|
398 |
$type = get_post_type( $post->ID );
|
399 |
|
400 |
+
$enabled = in_array( $type, ezTOC_Option::get( 'enabled_post_types', array() ), true );
|
401 |
+
$insert = in_array( $type, ezTOC_Option::get( 'auto_insert_post_types', array() ), true );
|
402 |
|
403 |
if ( $insert || $enabled ) {
|
404 |
|
includes/class.post.php
CHANGED
@@ -799,10 +799,17 @@ class ezTOC_Post {
|
|
799 |
//$return = preg_replace( '/[^a-zA-Z0-9 \-_]*/', '', $return );
|
800 |
$return = preg_replace( '/[\x00-\x1F\x7F\-_]*/u', '', $return );
|
801 |
|
802 |
-
//
|
|
|
|
|
|
|
|
|
803 |
$return = preg_replace( '/\s+/', '_', $return );
|
804 |
|
805 |
-
//
|
|
|
|
|
|
|
806 |
$return = rtrim( $return, '-_' );
|
807 |
|
808 |
/*
|
799 |
//$return = preg_replace( '/[^a-zA-Z0-9 \-_]*/', '', $return );
|
800 |
$return = preg_replace( '/[\x00-\x1F\x7F\-_]*/u', '', $return );
|
801 |
|
802 |
+
// AMP/Caching plugins seems to break URL with the following characters, so lets replace them.
|
803 |
+
$return = str_replace( array( ':' ), '_', $return );
|
804 |
+
$return = str_replace( array( '.' ), ' ', $return );
|
805 |
+
|
806 |
+
// Convert space characters to an `_` (underscore).
|
807 |
$return = preg_replace( '/\s+/', '_', $return );
|
808 |
|
809 |
+
// Replace multiple `_` (underscore) with a single `_` (underscore).
|
810 |
+
$return = preg_replace( '/_+/', '_', $return );
|
811 |
+
|
812 |
+
// Remove trailing `-` (hyphen) and `_` (underscore).
|
813 |
$return = rtrim( $return, '-_' );
|
814 |
|
815 |
/*
|
includes/inc.plugin-compatibility.php
CHANGED
@@ -326,6 +326,22 @@ add_filter(
|
|
326 |
}
|
327 |
);
|
328 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
329 |
class ezTOC_Elementor {
|
330 |
|
331 |
/**
|
326 |
}
|
327 |
);
|
328 |
|
329 |
+
/**
|
330 |
+
* Remove the Contextual Related Posts node from the post content before extracting headings.
|
331 |
+
*
|
332 |
+
* @link https://wordpress.org/plugins/contextual-related-posts/
|
333 |
+
* @since 2.0.9
|
334 |
+
*/
|
335 |
+
add_filter(
|
336 |
+
'ez_toc_exclude_by_selector',
|
337 |
+
function( $selectors ) {
|
338 |
+
|
339 |
+
$selectors['contextual-related-posts'] = '.crp_related';
|
340 |
+
|
341 |
+
return $selectors;
|
342 |
+
}
|
343 |
+
);
|
344 |
+
|
345 |
class ezTOC_Elementor {
|
346 |
|
347 |
/**
|
includes/vendor/ultimate-web-scraper/crc32_stream.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
// CRC32 stream class.
|
3 |
-
// (C)
|
4 |
//
|
5 |
// Direct port from the CubicleSoft C++ implementation.
|
6 |
|
@@ -45,8 +45,8 @@
|
|
45 |
$y = strlen($data);
|
46 |
for ($x < 0; $x < $y; $x++)
|
47 |
{
|
48 |
-
if ($this->datareflect) $this->currcrc = $this->SHL32($this->currcrc, 8) ^ $this->crctable[$this->SHR32($this->currcrc, 24) ^ self::$revlookup[ord($data
|
49 |
-
else $this->currcrc = $this->SHL32($this->currcrc, 8) ^ $this->crctable[$this->SHR32($this->currcrc, 24) ^ ord($data
|
50 |
}
|
51 |
|
52 |
return true;
|
1 |
<?php
|
2 |
// CRC32 stream class.
|
3 |
+
// (C) 2020 CubicleSoft. All Rights Reserved.
|
4 |
//
|
5 |
// Direct port from the CubicleSoft C++ implementation.
|
6 |
|
45 |
$y = strlen($data);
|
46 |
for ($x < 0; $x < $y; $x++)
|
47 |
{
|
48 |
+
if ($this->datareflect) $this->currcrc = $this->SHL32($this->currcrc, 8) ^ $this->crctable[$this->SHR32($this->currcrc, 24) ^ self::$revlookup[ord($data[$x])]];
|
49 |
+
else $this->currcrc = $this->SHL32($this->currcrc, 8) ^ $this->crctable[$this->SHR32($this->currcrc, 24) ^ ord($data[$x])];
|
50 |
}
|
51 |
|
52 |
return true;
|
includes/vendor/ultimate-web-scraper/deflate_stream.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
// Deflate stream class. Default is RFC1951 (raw deflate). Supports RFC1950 (ZLIB) and RFC1952 (gzip).
|
3 |
-
// (C)
|
4 |
|
5 |
class DeflateStream
|
6 |
{
|
@@ -140,7 +140,7 @@
|
|
140 |
$y = strlen($data);
|
141 |
for ($x = 0; $x < $y; $x++)
|
142 |
{
|
143 |
-
$this->options["a"] = ($this->options["a"] + ord($data
|
144 |
$this->options["b"] = ($this->options["b"] + $this->options["a"]) % 65521;
|
145 |
}
|
146 |
}
|
@@ -225,7 +225,7 @@
|
|
225 |
$zlibtest = unpack("n", substr($this->indata, 0, 2));
|
226 |
|
227 |
if (substr($this->indata, 0, 3) === "\x1F\x8B\x08") $this->options["type"] = "gzip";
|
228 |
-
else if ((ord($this->indata
|
229 |
else $this->options["type"] = "raw";
|
230 |
}
|
231 |
else if ($final) $this->options["type"] = "raw";
|
@@ -238,7 +238,7 @@
|
|
238 |
if (strlen($this->indata) >= 10)
|
239 |
{
|
240 |
$idcm = substr($this->indata, 0, 3);
|
241 |
-
$flg = ord($this->indata
|
242 |
|
243 |
if ($idcm !== "\x1F\x8B\x08") $this->options["type"] = "ignore";
|
244 |
else
|
@@ -300,8 +300,8 @@
|
|
300 |
{
|
301 |
if (strlen($this->indata) >= 2)
|
302 |
{
|
303 |
-
$cmf = ord($this->indata
|
304 |
-
$flg = ord($this->indata
|
305 |
$cm = $cmf & 0x0F;
|
306 |
$cinfo = ($cmf & 0xF0) >> 4;
|
307 |
|
1 |
<?php
|
2 |
// Deflate stream class. Default is RFC1951 (raw deflate). Supports RFC1950 (ZLIB) and RFC1952 (gzip).
|
3 |
+
// (C) 2020 CubicleSoft. All Rights Reserved.
|
4 |
|
5 |
class DeflateStream
|
6 |
{
|
140 |
$y = strlen($data);
|
141 |
for ($x = 0; $x < $y; $x++)
|
142 |
{
|
143 |
+
$this->options["a"] = ($this->options["a"] + ord($data[$x])) % 65521;
|
144 |
$this->options["b"] = ($this->options["b"] + $this->options["a"]) % 65521;
|
145 |
}
|
146 |
}
|
225 |
$zlibtest = unpack("n", substr($this->indata, 0, 2));
|
226 |
|
227 |
if (substr($this->indata, 0, 3) === "\x1F\x8B\x08") $this->options["type"] = "gzip";
|
228 |
+
else if ((ord($this->indata[0]) & 0x0F) == 8 && ((ord($this->indata[0]) & 0xF0) >> 4) < 8 && $zlibtest[1] % 31 == 0) $this->options["type"] = "zlib";
|
229 |
else $this->options["type"] = "raw";
|
230 |
}
|
231 |
else if ($final) $this->options["type"] = "raw";
|
238 |
if (strlen($this->indata) >= 10)
|
239 |
{
|
240 |
$idcm = substr($this->indata, 0, 3);
|
241 |
+
$flg = ord($this->indata[3]);
|
242 |
|
243 |
if ($idcm !== "\x1F\x8B\x08") $this->options["type"] = "ignore";
|
244 |
else
|
300 |
{
|
301 |
if (strlen($this->indata) >= 2)
|
302 |
{
|
303 |
+
$cmf = ord($this->indata[0]);
|
304 |
+
$flg = ord($this->indata[1]);
|
305 |
$cm = $cmf & 0x0F;
|
306 |
$cinfo = ($cmf & 0xF0) >> 4;
|
307 |
|
includes/vendor/ultimate-web-scraper/http.php
CHANGED
@@ -265,13 +265,14 @@
|
|
265 |
|
266 |
public static function GetSafeSSLOpts($cafile = true, $cipherstype = "intermediate")
|
267 |
{
|
268 |
-
// Result array last updated
|
269 |
$result = array(
|
270 |
"ciphers" => self::GetSSLCiphers($cipherstype),
|
271 |
"disable_compression" => true,
|
272 |
"allow_self_signed" => false,
|
273 |
"verify_peer" => true,
|
274 |
-
"verify_depth" => 5
|
|
|
275 |
);
|
276 |
|
277 |
if ($cafile === true) $result["auto_cainfo"] = true;
|
@@ -452,6 +453,18 @@
|
|
452 |
else if (file_exists(str_replace("\\", "/", dirname(__FILE__)) . "/cacert.pem")) $options[$key]["cafile"] = str_replace("\\", "/", dirname(__FILE__)) . "/cacert.pem";
|
453 |
}
|
454 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
455 |
if (isset($options[$key]["auto_cn_match"]))
|
456 |
{
|
457 |
unset($options[$key]["auto_cn_match"]);
|
@@ -722,7 +735,7 @@
|
|
722 |
if ($state[$prefix . "data"] !== "")
|
723 |
{
|
724 |
// Serious bug in PHP core for non-blocking SSL sockets: https://bugs.php.net/bug.php?id=72333
|
725 |
-
if ($state["secure"] && $state["async"])
|
726 |
{
|
727 |
// This is a huge hack that has a pretty good chance of blocking on the socket.
|
728 |
// Peeling off up to just 4KB at a time helps to minimize that possibility. It's better than guaranteed failure of the socket though.
|
@@ -850,6 +863,8 @@
|
|
850 |
if ($state["async"] && function_exists("stream_socket_client") && (($state["useproxy"] && $state["proxysecure"]) || (!$state["useproxy"] && $state["secure"]))) $state["state"] = "connecting_enable_crypto";
|
851 |
else $state["state"] = "connection_ready";
|
852 |
|
|
|
|
|
853 |
break;
|
854 |
}
|
855 |
case "connecting_enable_crypto":
|
@@ -861,6 +876,8 @@
|
|
861 |
if ($result === false) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("A stream_socket_enable_crypto() failure occurred. Most likely cause: Connection failure or incompatible crypto setup."), "errorcode" => "stream_socket_enable_crypto_failed"));
|
862 |
else if ($result === true) $state["state"] = "connection_ready";
|
863 |
|
|
|
|
|
864 |
break;
|
865 |
}
|
866 |
case "connection_ready":
|
@@ -910,6 +927,8 @@
|
|
910 |
$state["state"] = "send_data";
|
911 |
}
|
912 |
|
|
|
|
|
913 |
break;
|
914 |
}
|
915 |
case "proxy_connect_send":
|
@@ -928,9 +947,12 @@
|
|
928 |
$options2["debug_callback_opts"] = $state["options"]["debug_callback_opts"];
|
929 |
}
|
930 |
$state["proxyresponse"] = self::InitResponseState($state["fp"], $state["debug"], $options2, $state["startts"], $state["timeout"], $state["result"], false, $state["nextread"]);
|
|
|
931 |
|
932 |
$state["state"] = "proxy_connect_response";
|
933 |
|
|
|
|
|
934 |
break;
|
935 |
}
|
936 |
case "proxy_connect_response":
|
@@ -950,6 +972,8 @@
|
|
950 |
if ($state["secure"]) $state["state"] = "proxy_connect_enable_crypto";
|
951 |
else $state["state"] = "send_data";
|
952 |
|
|
|
|
|
953 |
break;
|
954 |
}
|
955 |
case "proxy_connect_enable_crypto":
|
@@ -977,6 +1001,8 @@
|
|
977 |
|
978 |
// Secure connection established.
|
979 |
$state["state"] = "send_data";
|
|
|
|
|
980 |
}
|
981 |
|
982 |
break;
|
@@ -1100,7 +1126,12 @@
|
|
1100 |
// All done sending data.
|
1101 |
if ($state["data"] === "")
|
1102 |
{
|
1103 |
-
if ($state["client"])
|
|
|
|
|
|
|
|
|
|
|
1104 |
else
|
1105 |
{
|
1106 |
$state["result"]["endts"] = microtime(true);
|
@@ -1130,6 +1161,8 @@
|
|
1130 |
|
1131 |
$state["state"] = "done";
|
1132 |
|
|
|
|
|
1133 |
break;
|
1134 |
}
|
1135 |
}
|
@@ -1171,6 +1204,8 @@
|
|
1171 |
$state["result"]["headers"] = array();
|
1172 |
$state["lastheader"] = "";
|
1173 |
|
|
|
|
|
1174 |
break;
|
1175 |
}
|
1176 |
case "request_line":
|
@@ -1217,6 +1252,8 @@
|
|
1217 |
$state["result"]["headers"] = array();
|
1218 |
$state["lastheader"] = "";
|
1219 |
|
|
|
|
|
1220 |
break;
|
1221 |
}
|
1222 |
case "headers":
|
@@ -1253,13 +1290,23 @@
|
|
1253 |
}
|
1254 |
|
1255 |
// Additional headers (optional) are the last bit of data in a chunked response.
|
1256 |
-
if ($state["state"] === "body_chunked_headers")
|
|
|
|
|
|
|
|
|
|
|
1257 |
else
|
1258 |
{
|
1259 |
$state["result"]["body"] = "";
|
1260 |
|
1261 |
// Handle 100 Continue below OR WebSocket among other things by letting the caller handle reading the body.
|
1262 |
-
if ($state["result"]["response"]["code"] == 100 || $state["result"]["response"]["code"] == 101)
|
|
|
|
|
|
|
|
|
|
|
1263 |
else
|
1264 |
{
|
1265 |
// Determine if decoding the content is possible and necessary.
|
@@ -1282,11 +1329,13 @@
|
|
1282 |
else
|
1283 |
{
|
1284 |
$state["sizeleft"] = (isset($state["result"]["headers"]["Content-Length"]) ? (double)preg_replace('/[^0-9]/', "", $state["result"]["headers"]["Content-Length"][0]) : false);
|
1285 |
-
$state["state"] = ($state["sizeleft"] !== false || $state["client"] ? "body_content" : "done");
|
1286 |
}
|
1287 |
|
|
|
|
|
1288 |
// Let servers have a chance to alter limits before processing the input body.
|
1289 |
-
if (!$state["client"] && $state["state"] !== "done")
|
1290 |
}
|
1291 |
}
|
1292 |
}
|
@@ -1324,6 +1373,8 @@
|
|
1324 |
$state["sizeleft"] = $size2;
|
1325 |
$state["state"] = "body_chunked_data";
|
1326 |
|
|
|
|
|
1327 |
break;
|
1328 |
}
|
1329 |
case "body_chunked_data":
|
@@ -1338,6 +1389,8 @@
|
|
1338 |
$state["state"] = "body_chunked_headers";
|
1339 |
}
|
1340 |
|
|
|
|
|
1341 |
break;
|
1342 |
}
|
1343 |
case "body_chunked_skipline":
|
@@ -1352,6 +1405,8 @@
|
|
1352 |
|
1353 |
$state["state"] = "body_chunked_size";
|
1354 |
|
|
|
|
|
1355 |
break;
|
1356 |
}
|
1357 |
case "body_content":
|
@@ -1361,6 +1416,8 @@
|
|
1361 |
|
1362 |
$state["state"] = "body_finalize";
|
1363 |
|
|
|
|
|
1364 |
break;
|
1365 |
}
|
1366 |
case "body_finalize":
|
@@ -1376,6 +1433,8 @@
|
|
1376 |
|
1377 |
$state["state"] = "done";
|
1378 |
|
|
|
|
|
1379 |
break;
|
1380 |
}
|
1381 |
}
|
@@ -1388,6 +1447,8 @@
|
|
1388 |
$state["result"]["response"] = false;
|
1389 |
$state["result"]["headers"] = false;
|
1390 |
$state["result"]["body"] = false;
|
|
|
|
|
1391 |
}
|
1392 |
}
|
1393 |
|
@@ -1730,7 +1791,12 @@
|
|
1730 |
}
|
1731 |
else if ($secure)
|
1732 |
{
|
1733 |
-
if (!isset($options["sslopts"]) || !is_array($options["sslopts"]))
|
|
|
|
|
|
|
|
|
|
|
1734 |
self::ProcessSSLOptions($options, "sslopts", $host);
|
1735 |
foreach ($options["sslopts"] as $key => $val) @stream_context_set_option($context, "ssl", $key, $val);
|
1736 |
}
|
265 |
|
266 |
public static function GetSafeSSLOpts($cafile = true, $cipherstype = "intermediate")
|
267 |
{
|
268 |
+
// Result array last updated Feb 15, 2020.
|
269 |
$result = array(
|
270 |
"ciphers" => self::GetSSLCiphers($cipherstype),
|
271 |
"disable_compression" => true,
|
272 |
"allow_self_signed" => false,
|
273 |
"verify_peer" => true,
|
274 |
+
"verify_depth" => 5,
|
275 |
+
"SNI_enabled" => true
|
276 |
);
|
277 |
|
278 |
if ($cafile === true) $result["auto_cainfo"] = true;
|
453 |
else if (file_exists(str_replace("\\", "/", dirname(__FILE__)) . "/cacert.pem")) $options[$key]["cafile"] = str_replace("\\", "/", dirname(__FILE__)) . "/cacert.pem";
|
454 |
}
|
455 |
|
456 |
+
if (isset($options[$key]["auto_peer_name"]))
|
457 |
+
{
|
458 |
+
unset($options[$key]["auto_peer_name"]);
|
459 |
+
|
460 |
+
if (!isset($options["headers"]["Host"])) $options[$key]["peer_name"] = $host;
|
461 |
+
else
|
462 |
+
{
|
463 |
+
$info = self::ExtractURL("https://" . $options["headers"]["Host"]);
|
464 |
+
$options[$key]["peer_name"] = $info["host"];
|
465 |
+
}
|
466 |
+
}
|
467 |
+
|
468 |
if (isset($options[$key]["auto_cn_match"]))
|
469 |
{
|
470 |
unset($options[$key]["auto_cn_match"]);
|
735 |
if ($state[$prefix . "data"] !== "")
|
736 |
{
|
737 |
// Serious bug in PHP core for non-blocking SSL sockets: https://bugs.php.net/bug.php?id=72333
|
738 |
+
if ($state["secure"] && $state["async"] && version_compare(PHP_VERSION, "7.1.4") <= 0)
|
739 |
{
|
740 |
// This is a huge hack that has a pretty good chance of blocking on the socket.
|
741 |
// Peeling off up to just 4KB at a time helps to minimize that possibility. It's better than guaranteed failure of the socket though.
|
863 |
if ($state["async"] && function_exists("stream_socket_client") && (($state["useproxy"] && $state["proxysecure"]) || (!$state["useproxy"] && $state["secure"]))) $state["state"] = "connecting_enable_crypto";
|
864 |
else $state["state"] = "connection_ready";
|
865 |
|
866 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
867 |
+
|
868 |
break;
|
869 |
}
|
870 |
case "connecting_enable_crypto":
|
876 |
if ($result === false) return self::CleanupErrorState($state, array("success" => false, "error" => self::HTTPTranslate("A stream_socket_enable_crypto() failure occurred. Most likely cause: Connection failure or incompatible crypto setup."), "errorcode" => "stream_socket_enable_crypto_failed"));
|
877 |
else if ($result === true) $state["state"] = "connection_ready";
|
878 |
|
879 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
880 |
+
|
881 |
break;
|
882 |
}
|
883 |
case "connection_ready":
|
927 |
$state["state"] = "send_data";
|
928 |
}
|
929 |
|
930 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
931 |
+
|
932 |
break;
|
933 |
}
|
934 |
case "proxy_connect_send":
|
947 |
$options2["debug_callback_opts"] = $state["options"]["debug_callback_opts"];
|
948 |
}
|
949 |
$state["proxyresponse"] = self::InitResponseState($state["fp"], $state["debug"], $options2, $state["startts"], $state["timeout"], $state["result"], false, $state["nextread"]);
|
950 |
+
$state["proxyresponse"]["proxyconnect"] = true;
|
951 |
|
952 |
$state["state"] = "proxy_connect_response";
|
953 |
|
954 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
955 |
+
|
956 |
break;
|
957 |
}
|
958 |
case "proxy_connect_response":
|
972 |
if ($state["secure"]) $state["state"] = "proxy_connect_enable_crypto";
|
973 |
else $state["state"] = "send_data";
|
974 |
|
975 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
976 |
+
|
977 |
break;
|
978 |
}
|
979 |
case "proxy_connect_enable_crypto":
|
1001 |
|
1002 |
// Secure connection established.
|
1003 |
$state["state"] = "send_data";
|
1004 |
+
|
1005 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1006 |
}
|
1007 |
|
1008 |
break;
|
1126 |
// All done sending data.
|
1127 |
if ($state["data"] === "")
|
1128 |
{
|
1129 |
+
if ($state["client"])
|
1130 |
+
{
|
1131 |
+
$state["state"] = "receive_switch";
|
1132 |
+
|
1133 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1134 |
+
}
|
1135 |
else
|
1136 |
{
|
1137 |
$state["result"]["endts"] = microtime(true);
|
1161 |
|
1162 |
$state["state"] = "done";
|
1163 |
|
1164 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1165 |
+
|
1166 |
break;
|
1167 |
}
|
1168 |
}
|
1204 |
$state["result"]["headers"] = array();
|
1205 |
$state["lastheader"] = "";
|
1206 |
|
1207 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1208 |
+
|
1209 |
break;
|
1210 |
}
|
1211 |
case "request_line":
|
1252 |
$state["result"]["headers"] = array();
|
1253 |
$state["lastheader"] = "";
|
1254 |
|
1255 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1256 |
+
|
1257 |
break;
|
1258 |
}
|
1259 |
case "headers":
|
1290 |
}
|
1291 |
|
1292 |
// Additional headers (optional) are the last bit of data in a chunked response.
|
1293 |
+
if ($state["state"] === "body_chunked_headers")
|
1294 |
+
{
|
1295 |
+
$state["state"] = "body_finalize";
|
1296 |
+
|
1297 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1298 |
+
}
|
1299 |
else
|
1300 |
{
|
1301 |
$state["result"]["body"] = "";
|
1302 |
|
1303 |
// Handle 100 Continue below OR WebSocket among other things by letting the caller handle reading the body.
|
1304 |
+
if ($state["result"]["response"]["code"] == 100 || $state["result"]["response"]["code"] == 101)
|
1305 |
+
{
|
1306 |
+
$state["state"] = "done";
|
1307 |
+
|
1308 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1309 |
+
}
|
1310 |
else
|
1311 |
{
|
1312 |
// Determine if decoding the content is possible and necessary.
|
1329 |
else
|
1330 |
{
|
1331 |
$state["sizeleft"] = (isset($state["result"]["headers"]["Content-Length"]) ? (double)preg_replace('/[^0-9]/', "", $state["result"]["headers"]["Content-Length"][0]) : false);
|
1332 |
+
$state["state"] = (!isset($state["proxyconnect"]) && ($state["sizeleft"] !== false || $state["client"]) ? "body_content" : "done");
|
1333 |
}
|
1334 |
|
1335 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1336 |
+
|
1337 |
// Let servers have a chance to alter limits before processing the input body.
|
1338 |
+
if (!$state["client"] && $state["state"] !== "done") return array("success" => false, "error" => self::HTTPTranslate("Intermission for adjustments to limits."), "errorcode" => "no_data");
|
1339 |
}
|
1340 |
}
|
1341 |
}
|
1373 |
$state["sizeleft"] = $size2;
|
1374 |
$state["state"] = "body_chunked_data";
|
1375 |
|
1376 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1377 |
+
|
1378 |
break;
|
1379 |
}
|
1380 |
case "body_chunked_data":
|
1389 |
$state["state"] = "body_chunked_headers";
|
1390 |
}
|
1391 |
|
1392 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1393 |
+
|
1394 |
break;
|
1395 |
}
|
1396 |
case "body_chunked_skipline":
|
1405 |
|
1406 |
$state["state"] = "body_chunked_size";
|
1407 |
|
1408 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1409 |
+
|
1410 |
break;
|
1411 |
}
|
1412 |
case "body_content":
|
1416 |
|
1417 |
$state["state"] = "body_finalize";
|
1418 |
|
1419 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1420 |
+
|
1421 |
break;
|
1422 |
}
|
1423 |
case "body_finalize":
|
1433 |
|
1434 |
$state["state"] = "done";
|
1435 |
|
1436 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1437 |
+
|
1438 |
break;
|
1439 |
}
|
1440 |
}
|
1447 |
$state["result"]["response"] = false;
|
1448 |
$state["result"]["headers"] = false;
|
1449 |
$state["result"]["body"] = false;
|
1450 |
+
|
1451 |
+
if (isset($state["options"]["debug_callback"]) && is_callable($state["options"]["debug_callback"])) call_user_func_array($state["options"]["debug_callback"], array("nextstate", $state["state"], &$state["options"]["debug_callback_opts"]));
|
1452 |
}
|
1453 |
}
|
1454 |
|
1791 |
}
|
1792 |
else if ($secure)
|
1793 |
{
|
1794 |
+
if (!isset($options["sslopts"]) || !is_array($options["sslopts"]))
|
1795 |
+
{
|
1796 |
+
$options["sslopts"] = self::GetSafeSSLOpts();
|
1797 |
+
$options["sslopts"]["auto_peer_name"] = true;
|
1798 |
+
}
|
1799 |
+
|
1800 |
self::ProcessSSLOptions($options, "sslopts", $host);
|
1801 |
foreach ($options["sslopts"] as $key => $val) @stream_context_set_option($context, "ssl", $key, $val);
|
1802 |
}
|
includes/vendor/ultimate-web-scraper/tag_filter.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
// CubicleSoft PHP Tag Filter class. Can repair broken HTML.
|
3 |
-
// (C)
|
4 |
|
5 |
class TagFilterStream
|
6 |
{
|
@@ -70,7 +70,7 @@
|
|
70 |
$startpos = $cx + 1;
|
71 |
for ($x = $startpos; $x < $cy; $x++)
|
72 |
{
|
73 |
-
$val = ord($content
|
74 |
if (($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2))
|
75 |
{
|
76 |
if ($x > $cx + 1) $prefix = ltrim(substr($content, $cx + 1, $x - $cx - 1));
|
@@ -83,7 +83,7 @@
|
|
83 |
if ($prefix === "") $open = true;
|
84 |
else
|
85 |
{
|
86 |
-
if ($prefix
|
87 |
{
|
88 |
// !DOCTYPE vs. comment.
|
89 |
if (substr($prefix, 0, 3) !== "!--")
|
@@ -126,13 +126,13 @@
|
|
126 |
continue;
|
127 |
}
|
128 |
}
|
129 |
-
else if ($prefix
|
130 |
{
|
131 |
// Close tag.
|
132 |
$prefix = "/";
|
133 |
$open = false;
|
134 |
}
|
135 |
-
else if ($prefix
|
136 |
{
|
137 |
// Stray less than. Encode and reset.
|
138 |
$content2 = "<";
|
@@ -171,7 +171,7 @@
|
|
171 |
$cx = $startpos;
|
172 |
for (; $cx < $cy; $cx++)
|
173 |
{
|
174 |
-
$val = ord($content
|
175 |
if ($val > 127) $parse = true;
|
176 |
else if (!(($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2) || ($cx > $startpos && (($val >= $zero && $val <= $nine) || $val == $hyphen || $val == $underscore || $val == $period)) || ($this->options["allow_namespaces"] && $val == $colon))) break;
|
177 |
}
|
@@ -241,7 +241,7 @@
|
|
241 |
// Find attribute key/property.
|
242 |
for ($x = $cx; $x < $cy; $x++)
|
243 |
{
|
244 |
-
if ($content
|
245 |
{
|
246 |
$cx = $x;
|
247 |
|
@@ -249,7 +249,7 @@
|
|
249 |
|
250 |
break;
|
251 |
}
|
252 |
-
else if ($content
|
253 |
{
|
254 |
$pos = strpos($content, ">", $x + 1);
|
255 |
if ($pos !== false && trim(substr($content, $x + 1, $pos - $x - 1)) === "")
|
@@ -262,10 +262,10 @@
|
|
262 |
break;
|
263 |
}
|
264 |
}
|
265 |
-
else if ($content
|
266 |
{
|
267 |
-
$pos = strpos($content, $content
|
268 |
-
if ($pos === false) $content .= $content
|
269 |
else if (isset($this->options["untouched_tag_attr_keys"][$tagname]))
|
270 |
{
|
271 |
$keyname = substr($content, $x, $pos - $x + 1);
|
@@ -298,7 +298,7 @@
|
|
298 |
}
|
299 |
else
|
300 |
{
|
301 |
-
$val = ord($content
|
302 |
if (($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2))
|
303 |
{
|
304 |
$cx = $x;
|
@@ -306,8 +306,8 @@
|
|
306 |
|
307 |
for (; $cx < $cy; $cx++)
|
308 |
{
|
309 |
-
if ($content
|
310 |
-
else if (ord($content
|
311 |
}
|
312 |
|
313 |
$keyname = substr($content, $x, $cx - $x);
|
@@ -342,7 +342,7 @@
|
|
342 |
// Find the equals sign OR the start of the next attribute/property.
|
343 |
for ($x = $cx; $x < $cy; $x++)
|
344 |
{
|
345 |
-
if ($content
|
346 |
{
|
347 |
$cx = $x;
|
348 |
|
@@ -352,7 +352,7 @@
|
|
352 |
|
353 |
break;
|
354 |
}
|
355 |
-
else if ($content
|
356 |
{
|
357 |
$cx = $x + 1;
|
358 |
|
@@ -360,7 +360,7 @@
|
|
360 |
|
361 |
break;
|
362 |
}
|
363 |
-
else if ($content
|
364 |
{
|
365 |
$cx = $x;
|
366 |
|
@@ -372,7 +372,7 @@
|
|
372 |
}
|
373 |
else
|
374 |
{
|
375 |
-
$val = ord($content
|
376 |
if (($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2) || ($val >= $zero && $val <= $nine))
|
377 |
{
|
378 |
$cx = $x;
|
@@ -399,7 +399,7 @@
|
|
399 |
{
|
400 |
for ($x = $cx; $x < $cy; $x++)
|
401 |
{
|
402 |
-
if ($content
|
403 |
{
|
404 |
$cx = $x;
|
405 |
|
@@ -409,10 +409,10 @@
|
|
409 |
|
410 |
break;
|
411 |
}
|
412 |
-
else if ($content
|
413 |
{
|
414 |
-
$pos = strpos($content, $content
|
415 |
-
if ($pos === false) $content .= $content
|
416 |
else
|
417 |
{
|
418 |
$value = substr($content, $x + 1, $pos - $x - 1);
|
@@ -423,13 +423,13 @@
|
|
423 |
|
424 |
break;
|
425 |
}
|
426 |
-
else if ($content
|
427 |
{
|
428 |
$cx = $x;
|
429 |
|
430 |
for (; $cx < $cy; $cx++)
|
431 |
{
|
432 |
-
if ($content
|
433 |
{
|
434 |
break;
|
435 |
}
|
@@ -474,20 +474,20 @@
|
|
474 |
$vx = $pos + 2;
|
475 |
if ($vx < $vy)
|
476 |
{
|
477 |
-
if ($value
|
478 |
{
|
479 |
$vx++;
|
480 |
if ($vx < $vy)
|
481 |
{
|
482 |
for ($x = $vx; $x < $vy; $x++)
|
483 |
{
|
484 |
-
$val = ord($value
|
485 |
if (!(($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))) break;
|
486 |
}
|
487 |
|
488 |
$num = hexdec(substr($value, $vx, $x - $vx));
|
489 |
$vx = $x;
|
490 |
-
if ($vx < $vy && $value
|
491 |
|
492 |
$value2 .= self::UTF8Chr($num);
|
493 |
}
|
@@ -496,13 +496,13 @@
|
|
496 |
{
|
497 |
for ($x = $vx; $x < $vy; $x++)
|
498 |
{
|
499 |
-
$val = ord($value
|
500 |
if (!($val >= $zero && $val <= $nine)) break;
|
501 |
}
|
502 |
|
503 |
$num = (int)substr($value, $vx, $x - $vx);
|
504 |
$vx = $x;
|
505 |
-
if ($vx < $vy && $value
|
506 |
|
507 |
$value2 .= self::UTF8Chr($num);
|
508 |
}
|
@@ -518,7 +518,7 @@
|
|
518 |
{
|
519 |
for ($x = $vx; $x < $vy; $x++)
|
520 |
{
|
521 |
-
$val = ord($value
|
522 |
if (!(($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))) break;
|
523 |
}
|
524 |
|
@@ -580,7 +580,7 @@
|
|
580 |
|
581 |
unset($attrs[""]);
|
582 |
|
583 |
-
if ($cx < $cy && $content
|
584 |
|
585 |
if (isset($this->options["tag_name_map"][$prefix . $tagname])) $outtagname = $tagname = $this->options["tag_name_map"][$prefix . $tagname];
|
586 |
|
@@ -899,19 +899,19 @@
|
|
899 |
$y = strlen($data);
|
900 |
while ($x < $y)
|
901 |
{
|
902 |
-
$tempchr = ord($data
|
903 |
if (($tempchr >= 0x20 && $tempchr <= 0x7E) || $tempchr == 0x09 || $tempchr == 0x0A || $tempchr == 0x0D) $x++;
|
904 |
else if ($tempchr < 0xC2) return false;
|
905 |
else
|
906 |
{
|
907 |
$left = $y - $x;
|
908 |
-
if ($left > 1) $tempchr2 = ord($data
|
909 |
else return false;
|
910 |
|
911 |
if (($tempchr >= 0xC2 && $tempchr <= 0xDF) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF)) $x += 2;
|
912 |
else
|
913 |
{
|
914 |
-
if ($left > 2) $tempchr3 = ord($data
|
915 |
else return false;
|
916 |
|
917 |
if ($tempchr3 < 0x80 || $tempchr3 > 0xBF) return false;
|
@@ -921,7 +921,7 @@
|
|
921 |
else if ($tempchr == 0xED && ($tempchr2 >= 0x80 && $tempchr2 <= 0x9F)) $x += 3;
|
922 |
else
|
923 |
{
|
924 |
-
if ($left > 3) $tempchr4 = ord($data
|
925 |
else return false;
|
926 |
|
927 |
if ($tempchr4 < 0x80 || $tempchr4 > 0xBF) return false;
|
@@ -2642,7 +2642,7 @@
|
|
2642 |
{
|
2643 |
if ($cx >= $cy) break;
|
2644 |
|
2645 |
-
switch ($query
|
2646 |
{
|
2647 |
case "#":
|
2648 |
{
|
@@ -2683,14 +2683,14 @@
|
|
2683 |
$cx++;
|
2684 |
|
2685 |
// Find a non-whitespace character.
|
2686 |
-
while ($cx < $cy && ($query
|
2687 |
|
2688 |
break;
|
2689 |
}
|
2690 |
case ":":
|
2691 |
{
|
2692 |
$cx++;
|
2693 |
-
if ($cx >= $cy || $query
|
2694 |
else
|
2695 |
{
|
2696 |
$token["type"] = "pseudo-element";
|
@@ -2771,9 +2771,9 @@
|
|
2771 |
$token[$state2] = $ident;
|
2772 |
|
2773 |
// Find a non-whitespace character.
|
2774 |
-
while ($cx < $cy && ($query
|
2775 |
|
2776 |
-
if ($cx >= $cy || $query
|
2777 |
{
|
2778 |
$token["cmp"] = false;
|
2779 |
$tokens[] = $token;
|
@@ -2782,28 +2782,28 @@
|
|
2782 |
}
|
2783 |
else
|
2784 |
{
|
2785 |
-
if ($query
|
2786 |
{
|
2787 |
$token["cmp"] = "=";
|
2788 |
$cx++;
|
2789 |
}
|
2790 |
-
else if ($cx + 1 < $cy && ($query
|
2791 |
{
|
2792 |
$token["cmp"] = substr($query, $cx, 2);
|
2793 |
$cx += 2;
|
2794 |
}
|
2795 |
else
|
2796 |
{
|
2797 |
-
return array("success" => false, "error" => "Unknown or invalid attribute comparison operator '" . $query
|
2798 |
}
|
2799 |
|
2800 |
// Find a non-whitespace character.
|
2801 |
-
while ($cx < $cy && ($query
|
2802 |
|
2803 |
-
if ($cx < $cy && ($query
|
2804 |
{
|
2805 |
$state = "string";
|
2806 |
-
$endchr = ord($query
|
2807 |
$cx++;
|
2808 |
}
|
2809 |
else
|
@@ -2823,12 +2823,12 @@
|
|
2823 |
$token[$state2] = $ident;
|
2824 |
|
2825 |
// Find a non-whitespace character.
|
2826 |
-
while ($cx < $cy && ($query
|
2827 |
|
2828 |
$tokens[] = $token;
|
2829 |
$state = ($token["not"] ? "negate_close" : "next_selector");
|
2830 |
|
2831 |
-
if ($cx < $cy && $query
|
2832 |
}
|
2833 |
|
2834 |
break;
|
@@ -2844,7 +2844,7 @@
|
|
2844 |
if ($token["type"] == "pseudo-class" && $ident == "not")
|
2845 |
{
|
2846 |
if ($token["not"]) return array("success" => false, "error" => "Invalid :not() embedded inside another :not() detected at position " . $cx . ".", "errorcode" => "invalid_not", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
|
2847 |
-
if ($cx >= $cy || $query
|
2848 |
|
2849 |
unset($token["type"]);
|
2850 |
$token["not"] = true;
|
@@ -2853,13 +2853,13 @@
|
|
2853 |
$cx++;
|
2854 |
|
2855 |
// Find a non-whitespace character.
|
2856 |
-
while ($cx < $cy && ($query
|
2857 |
}
|
2858 |
else
|
2859 |
{
|
2860 |
$token["pseudo"] = $ident;
|
2861 |
|
2862 |
-
if ($cx < $cy && $query
|
2863 |
{
|
2864 |
$token["expression"] = "";
|
2865 |
$ident = "";
|
@@ -2883,9 +2883,9 @@
|
|
2883 |
case "negate_close":
|
2884 |
{
|
2885 |
// Find a non-whitespace character.
|
2886 |
-
while ($cx < $cy && ($query
|
2887 |
|
2888 |
-
if ($cx < $cy && $query
|
2889 |
|
2890 |
$cx++;
|
2891 |
$state = "next_selector";
|
@@ -2897,11 +2897,11 @@
|
|
2897 |
$token["expression"] .= $ident;
|
2898 |
|
2899 |
// Find a non-whitespace character.
|
2900 |
-
while ($cx < $cy && ($query
|
2901 |
|
2902 |
if ($cx >= $cy) break;
|
2903 |
|
2904 |
-
if ($query
|
2905 |
{
|
2906 |
if (substr($token["pseudo"], 0, 4) === "nth-")
|
2907 |
{
|
@@ -2944,20 +2944,20 @@
|
|
2944 |
$state = ($token["not"] ? "negate_close" : "next_selector");
|
2945 |
$cx++;
|
2946 |
}
|
2947 |
-
else if ($query
|
2948 |
{
|
2949 |
-
$ident = $query
|
2950 |
$cx++;
|
2951 |
}
|
2952 |
-
else if ($query
|
2953 |
{
|
2954 |
$state = "string";
|
2955 |
-
$endchr = ord($query
|
2956 |
$cx++;
|
2957 |
}
|
2958 |
else
|
2959 |
{
|
2960 |
-
$val = ord($query
|
2961 |
|
2962 |
$state = ($val >= $zero && $val <= $nine ? "ident_name" : "ident");
|
2963 |
$allownamespace = false;
|
@@ -2979,7 +2979,7 @@
|
|
2979 |
|
2980 |
for (; $cx < $cy; $cx++)
|
2981 |
{
|
2982 |
-
$val = ord($query
|
2983 |
|
2984 |
if ($val == $endchr)
|
2985 |
{
|
@@ -2994,14 +2994,14 @@
|
|
2994 |
else
|
2995 |
{
|
2996 |
$cx++;
|
2997 |
-
$val = ord($query
|
2998 |
|
2999 |
if (($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))
|
3000 |
{
|
3001 |
// Unicode (e.g. \0020)
|
3002 |
for ($x = $cx + 1; $x < $cy; $x++)
|
3003 |
{
|
3004 |
-
$val = ord($query
|
3005 |
if (!(($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))) break;
|
3006 |
}
|
3007 |
|
@@ -3011,18 +3011,18 @@
|
|
3011 |
$ident .= TagFilterStream::UTF8Chr($num);
|
3012 |
|
3013 |
// Skip one optional \r\n OR a single whitespace char.
|
3014 |
-
if ($cx + 2 < $cy && $query
|
3015 |
-
else if ($cx + 1 < $cy && ($query
|
3016 |
}
|
3017 |
else
|
3018 |
{
|
3019 |
-
$ident .= $query
|
3020 |
}
|
3021 |
}
|
3022 |
}
|
3023 |
else
|
3024 |
{
|
3025 |
-
$ident .= $query
|
3026 |
}
|
3027 |
}
|
3028 |
|
@@ -3037,7 +3037,7 @@
|
|
3037 |
|
3038 |
if ($cx >= $cy) break;
|
3039 |
|
3040 |
-
if ($query
|
3041 |
else
|
3042 |
{
|
3043 |
$ident = "-";
|
@@ -3054,13 +3054,13 @@
|
|
3054 |
$startcx = $cx;
|
3055 |
for (; $cx < $cy; $cx++)
|
3056 |
{
|
3057 |
-
$val = ord($query
|
3058 |
|
3059 |
if ($val != $period && ($val < $zero || $val > $nine)) $allowperiod = false;
|
3060 |
|
3061 |
if (($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2) || $val == $underscore || $val > 127)
|
3062 |
{
|
3063 |
-
$ident .= $query
|
3064 |
}
|
3065 |
else if ($allowperiod && $val == $period)
|
3066 |
{
|
@@ -3071,11 +3071,11 @@
|
|
3071 |
else if ($val == $hyphen || ($val >= $zero && $val <= $nine))
|
3072 |
{
|
3073 |
// Only allowed AFTER the first character.
|
3074 |
-
if (!$range) return array("success" => false, "error" => "Invalid identifier character '" . $query
|
3075 |
|
3076 |
$allowperiod = false;
|
3077 |
|
3078 |
-
$ident .= $query
|
3079 |
}
|
3080 |
else if ($val == $backslash)
|
3081 |
{
|
@@ -3084,14 +3084,14 @@
|
|
3084 |
else
|
3085 |
{
|
3086 |
$cx++;
|
3087 |
-
$val = ord($query
|
3088 |
|
3089 |
if (($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))
|
3090 |
{
|
3091 |
// Unicode (e.g. \0020)
|
3092 |
for ($x = $cx + 1; $x < $cy; $x++)
|
3093 |
{
|
3094 |
-
$val = ord($query
|
3095 |
if (!(($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))) break;
|
3096 |
}
|
3097 |
|
@@ -3101,16 +3101,16 @@
|
|
3101 |
$ident .= TagFilterStream::UTF8Chr($num);
|
3102 |
|
3103 |
// Skip one optional \r\n OR a single whitespace char.
|
3104 |
-
if ($cx + 2 < $cy && $query
|
3105 |
-
else if ($cx + 1 < $cy && ($query
|
3106 |
}
|
3107 |
else if ($val != $cr && $val != $nl && $val != $ff)
|
3108 |
{
|
3109 |
-
$ident .= $query
|
3110 |
}
|
3111 |
}
|
3112 |
}
|
3113 |
-
else if ($allownamespace && $val == $pipe && ($cx + 1 >= $cy || $query
|
3114 |
{
|
3115 |
// Handle namespaces (rare).
|
3116 |
if ($ident != "")
|
@@ -3124,7 +3124,7 @@
|
|
3124 |
else if ($val == $asterisk)
|
3125 |
{
|
3126 |
// Handle wildcard (*) characters.
|
3127 |
-
if ($allownamespace && $cx + 1 < $cy && $query
|
3128 |
{
|
3129 |
// Wildcard namespace (*|).
|
3130 |
$namespace = "*";
|
@@ -3166,11 +3166,11 @@
|
|
3166 |
$token = array("type" => "combine");
|
3167 |
|
3168 |
// Find a non-whitespace character.
|
3169 |
-
while ($cx < $cy && ($query
|
3170 |
|
3171 |
if ($cx < $cy)
|
3172 |
{
|
3173 |
-
switch ($query
|
3174 |
{
|
3175 |
case ",":
|
3176 |
{
|
@@ -3214,7 +3214,7 @@
|
|
3214 |
$tokens[] = $token;
|
3215 |
|
3216 |
// Find a non-whitespace character.
|
3217 |
-
while ($cx < $cy && ($query
|
3218 |
}
|
3219 |
|
3220 |
$state = "next_selector";
|
@@ -3257,4 +3257,4 @@
|
|
3257 |
return false;
|
3258 |
}
|
3259 |
}
|
3260 |
-
?>
|
1 |
<?php
|
2 |
// CubicleSoft PHP Tag Filter class. Can repair broken HTML.
|
3 |
+
// (C) 2020 CubicleSoft. All Rights Reserved.
|
4 |
|
5 |
class TagFilterStream
|
6 |
{
|
70 |
$startpos = $cx + 1;
|
71 |
for ($x = $startpos; $x < $cy; $x++)
|
72 |
{
|
73 |
+
$val = ord($content[$x]);
|
74 |
if (($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2))
|
75 |
{
|
76 |
if ($x > $cx + 1) $prefix = ltrim(substr($content, $cx + 1, $x - $cx - 1));
|
83 |
if ($prefix === "") $open = true;
|
84 |
else
|
85 |
{
|
86 |
+
if ($prefix[0] === "!")
|
87 |
{
|
88 |
// !DOCTYPE vs. comment.
|
89 |
if (substr($prefix, 0, 3) !== "!--")
|
126 |
continue;
|
127 |
}
|
128 |
}
|
129 |
+
else if ($prefix[0] === "/")
|
130 |
{
|
131 |
// Close tag.
|
132 |
$prefix = "/";
|
133 |
$open = false;
|
134 |
}
|
135 |
+
else if ($prefix[0] === "<")
|
136 |
{
|
137 |
// Stray less than. Encode and reset.
|
138 |
$content2 = "<";
|
171 |
$cx = $startpos;
|
172 |
for (; $cx < $cy; $cx++)
|
173 |
{
|
174 |
+
$val = ord($content[$cx]);
|
175 |
if ($val > 127) $parse = true;
|
176 |
else if (!(($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2) || ($cx > $startpos && (($val >= $zero && $val <= $nine) || $val == $hyphen || $val == $underscore || $val == $period)) || ($this->options["allow_namespaces"] && $val == $colon))) break;
|
177 |
}
|
241 |
// Find attribute key/property.
|
242 |
for ($x = $cx; $x < $cy; $x++)
|
243 |
{
|
244 |
+
if ($content[$x] === ">" || $content[$x] === "<")
|
245 |
{
|
246 |
$cx = $x;
|
247 |
|
249 |
|
250 |
break;
|
251 |
}
|
252 |
+
else if ($content[$x] === "/")
|
253 |
{
|
254 |
$pos = strpos($content, ">", $x + 1);
|
255 |
if ($pos !== false && trim(substr($content, $x + 1, $pos - $x - 1)) === "")
|
262 |
break;
|
263 |
}
|
264 |
}
|
265 |
+
else if ($content[$x] === "\"" || $content[$x] === "'" || $content[$x] === "`")
|
266 |
{
|
267 |
+
$pos = strpos($content, $content[$x], $x + 1);
|
268 |
+
if ($pos === false) $content .= $content[$x];
|
269 |
else if (isset($this->options["untouched_tag_attr_keys"][$tagname]))
|
270 |
{
|
271 |
$keyname = substr($content, $x, $pos - $x + 1);
|
298 |
}
|
299 |
else
|
300 |
{
|
301 |
+
$val = ord($content[$x]);
|
302 |
if (($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2))
|
303 |
{
|
304 |
$cx = $x;
|
306 |
|
307 |
for (; $cx < $cy; $cx++)
|
308 |
{
|
309 |
+
if ($content[$cx] === " " || $content[$cx] === "=" || $content[$cx] === "\"" || $content[$cx] === "'" || $content[$cx] === "`" || $content[$cx] === ">" || $content[$cx] === "<" || $content[$cx] === "/" || $content[$cx] === "\0" || $content[$cx] === "\r" || $content[$cx] === "\n" || $content[$cx] === "\t") break;
|
310 |
+
else if (ord($content[$cx]) > 127) $parse = true;
|
311 |
}
|
312 |
|
313 |
$keyname = substr($content, $x, $cx - $x);
|
342 |
// Find the equals sign OR the start of the next attribute/property.
|
343 |
for ($x = $cx; $x < $cy; $x++)
|
344 |
{
|
345 |
+
if ($content[$x] === ">" || $content[$x] === "<")
|
346 |
{
|
347 |
$cx = $x;
|
348 |
|
352 |
|
353 |
break;
|
354 |
}
|
355 |
+
else if ($content[$x] === "=")
|
356 |
{
|
357 |
$cx = $x + 1;
|
358 |
|
360 |
|
361 |
break;
|
362 |
}
|
363 |
+
else if ($content[$x] === "\"" || $content[$x] === "'")
|
364 |
{
|
365 |
$cx = $x;
|
366 |
|
372 |
}
|
373 |
else
|
374 |
{
|
375 |
+
$val = ord($content[$x]);
|
376 |
if (($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2) || ($val >= $zero && $val <= $nine))
|
377 |
{
|
378 |
$cx = $x;
|
399 |
{
|
400 |
for ($x = $cx; $x < $cy; $x++)
|
401 |
{
|
402 |
+
if ($content[$x] === ">" || $content[$x] === "<")
|
403 |
{
|
404 |
$cx = $x;
|
405 |
|
409 |
|
410 |
break;
|
411 |
}
|
412 |
+
else if ($content[$x] === "\"" || $content[$x] === "'" || $content[$x] === "`")
|
413 |
{
|
414 |
+
$pos = strpos($content, $content[$x], $x + 1);
|
415 |
+
if ($pos === false) $content .= $content[$x];
|
416 |
else
|
417 |
{
|
418 |
$value = substr($content, $x + 1, $pos - $x - 1);
|
423 |
|
424 |
break;
|
425 |
}
|
426 |
+
else if ($content[$x] !== "\0" && $content[$x] !== "\r" && $content[$x] !== "\n" && $content[$x] !== "\t" && $content[$x] !== " ")
|
427 |
{
|
428 |
$cx = $x;
|
429 |
|
430 |
for (; $cx < $cy; $cx++)
|
431 |
{
|
432 |
+
if ($content[$cx] === "\0" || $content[$cx] === "\r" || $content[$cx] === "\n" || $content[$cx] === "\t" || $content[$cx] === " " || $content[$cx] === "<" || $content[$cx] === ">")
|
433 |
{
|
434 |
break;
|
435 |
}
|
474 |
$vx = $pos + 2;
|
475 |
if ($vx < $vy)
|
476 |
{
|
477 |
+
if ($value[$vx] == "x" || $value[$vx] == "X")
|
478 |
{
|
479 |
$vx++;
|
480 |
if ($vx < $vy)
|
481 |
{
|
482 |
for ($x = $vx; $x < $vy; $x++)
|
483 |
{
|
484 |
+
$val = ord($value[$x]);
|
485 |
if (!(($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))) break;
|
486 |
}
|
487 |
|
488 |
$num = hexdec(substr($value, $vx, $x - $vx));
|
489 |
$vx = $x;
|
490 |
+
if ($vx < $vy && $value[$vx] == ";") $vx++;
|
491 |
|
492 |
$value2 .= self::UTF8Chr($num);
|
493 |
}
|
496 |
{
|
497 |
for ($x = $vx; $x < $vy; $x++)
|
498 |
{
|
499 |
+
$val = ord($value[$x]);
|
500 |
if (!($val >= $zero && $val <= $nine)) break;
|
501 |
}
|
502 |
|
503 |
$num = (int)substr($value, $vx, $x - $vx);
|
504 |
$vx = $x;
|
505 |
+
if ($vx < $vy && $value[$vx] == ";") $vx++;
|
506 |
|
507 |
$value2 .= self::UTF8Chr($num);
|
508 |
}
|
518 |
{
|
519 |
for ($x = $vx; $x < $vy; $x++)
|
520 |
{
|
521 |
+
$val = ord($value[$x]);
|
522 |
if (!(($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))) break;
|
523 |
}
|
524 |
|
580 |
|
581 |
unset($attrs[""]);
|
582 |
|
583 |
+
if ($cx < $cy && $content[$cx] === ">") $cx++;
|
584 |
|
585 |
if (isset($this->options["tag_name_map"][$prefix . $tagname])) $outtagname = $tagname = $this->options["tag_name_map"][$prefix . $tagname];
|
586 |
|
899 |
$y = strlen($data);
|
900 |
while ($x < $y)
|
901 |
{
|
902 |
+
$tempchr = ord($data[$x]);
|
903 |
if (($tempchr >= 0x20 && $tempchr <= 0x7E) || $tempchr == 0x09 || $tempchr == 0x0A || $tempchr == 0x0D) $x++;
|
904 |
else if ($tempchr < 0xC2) return false;
|
905 |
else
|
906 |
{
|
907 |
$left = $y - $x;
|
908 |
+
if ($left > 1) $tempchr2 = ord($data[$x + 1]);
|
909 |
else return false;
|
910 |
|
911 |
if (($tempchr >= 0xC2 && $tempchr <= 0xDF) && ($tempchr2 >= 0x80 && $tempchr2 <= 0xBF)) $x += 2;
|
912 |
else
|
913 |
{
|
914 |
+
if ($left > 2) $tempchr3 = ord($data[$x + 2]);
|
915 |
else return false;
|
916 |
|
917 |
if ($tempchr3 < 0x80 || $tempchr3 > 0xBF) return false;
|
921 |
else if ($tempchr == 0xED && ($tempchr2 >= 0x80 && $tempchr2 <= 0x9F)) $x += 3;
|
922 |
else
|
923 |
{
|
924 |
+
if ($left > 3) $tempchr4 = ord($data[$x + 3]);
|
925 |
else return false;
|
926 |
|
927 |
if ($tempchr4 < 0x80 || $tempchr4 > 0xBF) return false;
|
2642 |
{
|
2643 |
if ($cx >= $cy) break;
|
2644 |
|
2645 |
+
switch ($query[$cx])
|
2646 |
{
|
2647 |
case "#":
|
2648 |
{
|
2683 |
$cx++;
|
2684 |
|
2685 |
// Find a non-whitespace character.
|
2686 |
+
while ($cx < $cy && ($query[$cx] == " " || $query[$cx] == "\t" || $query[$cx] == "\r" || $query[$cx] == "\n" || $query[$cx] == "\f")) $cx++;
|
2687 |
|
2688 |
break;
|
2689 |
}
|
2690 |
case ":":
|
2691 |
{
|
2692 |
$cx++;
|
2693 |
+
if ($cx >= $cy || $query[$cx] != ":") $token["type"] = "pseudo-class";
|
2694 |
else
|
2695 |
{
|
2696 |
$token["type"] = "pseudo-element";
|
2771 |
$token[$state2] = $ident;
|
2772 |
|
2773 |
// Find a non-whitespace character.
|
2774 |
+
while ($cx < $cy && ($query[$cx] == " " || $query[$cx] == "\t" || $query[$cx] == "\r" || $query[$cx] == "\n" || $query[$cx] == "\f")) $cx++;
|
2775 |
|
2776 |
+
if ($cx >= $cy || $query[$cx] == "]")
|
2777 |
{
|
2778 |
$token["cmp"] = false;
|
2779 |
$tokens[] = $token;
|
2782 |
}
|
2783 |
else
|
2784 |
{
|
2785 |
+
if ($query[$cx] == "=")
|
2786 |
{
|
2787 |
$token["cmp"] = "=";
|
2788 |
$cx++;
|
2789 |
}
|
2790 |
+
else if ($cx + 1 < $cy && ($query[$cx] == "^" || $query[$cx] == "$" || $query[$cx] == "*" || $query[$cx] == "~" || $query[$cx] == "|") && $query[$cx + 1] == "=")
|
2791 |
{
|
2792 |
$token["cmp"] = substr($query, $cx, 2);
|
2793 |
$cx += 2;
|
2794 |
}
|
2795 |
else
|
2796 |
{
|
2797 |
+
return array("success" => false, "error" => "Unknown or invalid attribute comparison operator '" . $query[$cx] . "' detected at position " . $cx . ".", "errorcode" => "invalid_attr_compare", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
|
2798 |
}
|
2799 |
|
2800 |
// Find a non-whitespace character.
|
2801 |
+
while ($cx < $cy && ($query[$cx] == " " || $query[$cx] == "\t" || $query[$cx] == "\r" || $query[$cx] == "\n" || $query[$cx] == "\f")) $cx++;
|
2802 |
|
2803 |
+
if ($cx < $cy && ($query[$cx] == "\"" || $query[$cx] == "'"))
|
2804 |
{
|
2805 |
$state = "string";
|
2806 |
+
$endchr = ord($query[$cx]);
|
2807 |
$cx++;
|
2808 |
}
|
2809 |
else
|
2823 |
$token[$state2] = $ident;
|
2824 |
|
2825 |
// Find a non-whitespace character.
|
2826 |
+
while ($cx < $cy && ($query[$cx] == " " || $query[$cx] == "\t" || $query[$cx] == "\r" || $query[$cx] == "\n" || $query[$cx] == "\f")) $cx++;
|
2827 |
|
2828 |
$tokens[] = $token;
|
2829 |
$state = ($token["not"] ? "negate_close" : "next_selector");
|
2830 |
|
2831 |
+
if ($cx < $cy && $query[$cx] == "]") $cx++;
|
2832 |
}
|
2833 |
|
2834 |
break;
|
2844 |
if ($token["type"] == "pseudo-class" && $ident == "not")
|
2845 |
{
|
2846 |
if ($token["not"]) return array("success" => false, "error" => "Invalid :not() embedded inside another :not() detected at position " . $cx . ".", "errorcode" => "invalid_not", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
|
2847 |
+
if ($cx >= $cy || $query[$cx] != "(") return array("success" => false, "error" => "Missing '(' detected at position " . $cx . ".", "errorcode" => "invalid_not", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
|
2848 |
|
2849 |
unset($token["type"]);
|
2850 |
$token["not"] = true;
|
2853 |
$cx++;
|
2854 |
|
2855 |
// Find a non-whitespace character.
|
2856 |
+
while ($cx < $cy && ($query[$cx] == " " || $query[$cx] == "\t" || $query[$cx] == "\r" || $query[$cx] == "\n" || $query[$cx] == "\f")) $cx++;
|
2857 |
}
|
2858 |
else
|
2859 |
{
|
2860 |
$token["pseudo"] = $ident;
|
2861 |
|
2862 |
+
if ($cx < $cy && $query[$cx] == "(")
|
2863 |
{
|
2864 |
$token["expression"] = "";
|
2865 |
$ident = "";
|
2883 |
case "negate_close":
|
2884 |
{
|
2885 |
// Find a non-whitespace character.
|
2886 |
+
while ($cx < $cy && ($query[$cx] == " " || $query[$cx] == "\t" || $query[$cx] == "\r" || $query[$cx] == "\n" || $query[$cx] == "\f")) $cx++;
|
2887 |
|
2888 |
+
if ($cx < $cy && $query[$cx] != ")") return array("success" => false, "error" => "Invalid :not() close character '" . $query[$cx] . "' detected at position " . $cx . ".", "errorcode" => "invalid_negate_close", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
|
2889 |
|
2890 |
$cx++;
|
2891 |
$state = "next_selector";
|
2897 |
$token["expression"] .= $ident;
|
2898 |
|
2899 |
// Find a non-whitespace character.
|
2900 |
+
while ($cx < $cy && ($query[$cx] == " " || $query[$cx] == "\t" || $query[$cx] == "\r" || $query[$cx] == "\n" || $query[$cx] == "\f")) $cx++;
|
2901 |
|
2902 |
if ($cx >= $cy) break;
|
2903 |
|
2904 |
+
if ($query[$cx] == ")")
|
2905 |
{
|
2906 |
if (substr($token["pseudo"], 0, 4) === "nth-")
|
2907 |
{
|
2944 |
$state = ($token["not"] ? "negate_close" : "next_selector");
|
2945 |
$cx++;
|
2946 |
}
|
2947 |
+
else if ($query[$cx] == "+" || $query[$cx] == "-")
|
2948 |
{
|
2949 |
+
$ident = $query[$cx];
|
2950 |
$cx++;
|
2951 |
}
|
2952 |
+
else if ($query[$cx] == "\"" || $query[$cx] == "'")
|
2953 |
{
|
2954 |
$state = "string";
|
2955 |
+
$endchr = ord($query[$cx]);
|
2956 |
$cx++;
|
2957 |
}
|
2958 |
else
|
2959 |
{
|
2960 |
+
$val = ord($query[$cx]);
|
2961 |
|
2962 |
$state = ($val >= $zero && $val <= $nine ? "ident_name" : "ident");
|
2963 |
$allownamespace = false;
|
2979 |
|
2980 |
for (; $cx < $cy; $cx++)
|
2981 |
{
|
2982 |
+
$val = ord($query[$cx]);
|
2983 |
|
2984 |
if ($val == $endchr)
|
2985 |
{
|
2994 |
else
|
2995 |
{
|
2996 |
$cx++;
|
2997 |
+
$val = ord($query[$cx]);
|
2998 |
|
2999 |
if (($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))
|
3000 |
{
|
3001 |
// Unicode (e.g. \0020)
|
3002 |
for ($x = $cx + 1; $x < $cy; $x++)
|
3003 |
{
|
3004 |
+
$val = ord($query[$x]);
|
3005 |
if (!(($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))) break;
|
3006 |
}
|
3007 |
|
3011 |
$ident .= TagFilterStream::UTF8Chr($num);
|
3012 |
|
3013 |
// Skip one optional \r\n OR a single whitespace char.
|
3014 |
+
if ($cx + 2 < $cy && $query[$cx + 1] == "\r" && $query[$cx + 2] == "\n") $cx += 2;
|
3015 |
+
else if ($cx + 1 < $cy && ($query[$cx + 1] == " " || $query[$cx + 1] == "\r" || $query[$cx + 1] == "\n" || $query[$cx + 1] == "\t" || $query[$cx + 1] == "\f")) $cx++;
|
3016 |
}
|
3017 |
else
|
3018 |
{
|
3019 |
+
$ident .= $query[$cx];
|
3020 |
}
|
3021 |
}
|
3022 |
}
|
3023 |
else
|
3024 |
{
|
3025 |
+
$ident .= $query[$cx];
|
3026 |
}
|
3027 |
}
|
3028 |
|
3037 |
|
3038 |
if ($cx >= $cy) break;
|
3039 |
|
3040 |
+
if ($query[$cx] != "-") $ident = "";
|
3041 |
else
|
3042 |
{
|
3043 |
$ident = "-";
|
3054 |
$startcx = $cx;
|
3055 |
for (; $cx < $cy; $cx++)
|
3056 |
{
|
3057 |
+
$val = ord($query[$cx]);
|
3058 |
|
3059 |
if ($val != $period && ($val < $zero || $val > $nine)) $allowperiod = false;
|
3060 |
|
3061 |
if (($val >= $a && $val <= $z) || ($val >= $a2 && $val <= $z2) || $val == $underscore || $val > 127)
|
3062 |
{
|
3063 |
+
$ident .= $query[$cx];
|
3064 |
}
|
3065 |
else if ($allowperiod && $val == $period)
|
3066 |
{
|
3071 |
else if ($val == $hyphen || ($val >= $zero && $val <= $nine))
|
3072 |
{
|
3073 |
// Only allowed AFTER the first character.
|
3074 |
+
if (!$range) return array("success" => false, "error" => "Invalid identifier character '" . $query[$cx] . "' detected at position " . $cx . ".", "errorcode" => "invalid_ident", "selector" => $query, "startpos" => $currcx, "pos" => $cx, "state" => $currstate, "tokens" => self::ReorderSelectorTokens(array_slice($tokens, 0, $lastor), $splitrules), "splitrules" => $splitrules);
|
3075 |
|
3076 |
$allowperiod = false;
|
3077 |
|
3078 |
+
$ident .= $query[$cx];
|
3079 |
}
|
3080 |
else if ($val == $backslash)
|
3081 |
{
|
3084 |
else
|
3085 |
{
|
3086 |
$cx++;
|
3087 |
+
$val = ord($query[$cx]);
|
3088 |
|
3089 |
if (($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))
|
3090 |
{
|
3091 |
// Unicode (e.g. \0020)
|
3092 |
for ($x = $cx + 1; $x < $cy; $x++)
|
3093 |
{
|
3094 |
+
$val = ord($query[$x]);
|
3095 |
if (!(($val >= $a && $val <= $f) || ($val >= $a2 && $val <= $f2) || ($val >= $zero && $val <= $nine))) break;
|
3096 |
}
|
3097 |
|
3101 |
$ident .= TagFilterStream::UTF8Chr($num);
|
3102 |
|
3103 |
// Skip one optional \r\n OR a single whitespace char.
|
3104 |
+
if ($cx + 2 < $cy && $query[$cx + 1] == "\r" && $query[$cx + 2] == "\n") $cx += 2;
|
3105 |
+
else if ($cx + 1 < $cy && ($query[$cx + 1] == " " || $query[$cx + 1] == "\r" || $query[$cx + 1] == "\n" || $query[$cx + 1] == "\t" || $query[$cx + 1] == "\f")) $cx++;
|
3106 |
}
|
3107 |
else if ($val != $cr && $val != $nl && $val != $ff)
|
3108 |
{
|
3109 |
+
$ident .= $query[$cx];
|
3110 |
}
|
3111 |
}
|
3112 |
}
|
3113 |
+
else if ($allownamespace && $val == $pipe && ($cx + 1 >= $cy || $query[$cx + 1] != "="))
|
3114 |
{
|
3115 |
// Handle namespaces (rare).
|
3116 |
if ($ident != "")
|
3124 |
else if ($val == $asterisk)
|
3125 |
{
|
3126 |
// Handle wildcard (*) characters.
|
3127 |
+
if ($allownamespace && $cx + 1 < $cy && $query[$cx + 1] == "|")
|
3128 |
{
|
3129 |
// Wildcard namespace (*|).
|
3130 |
$namespace = "*";
|
3166 |
$token = array("type" => "combine");
|
3167 |
|
3168 |
// Find a non-whitespace character.
|
3169 |
+
while ($cx < $cy && ($query[$cx] == " " || $query[$cx] == "\t" || $query[$cx] == "\r" || $query[$cx] == "\n" || $query[$cx] == "\f")) $cx++;
|
3170 |
|
3171 |
if ($cx < $cy)
|
3172 |
{
|
3173 |
+
switch ($query[$cx])
|
3174 |
{
|
3175 |
case ",":
|
3176 |
{
|
3214 |
$tokens[] = $token;
|
3215 |
|
3216 |
// Find a non-whitespace character.
|
3217 |
+
while ($cx < $cy && ($query[$cx] == " " || $query[$cx] == "\t" || $query[$cx] == "\r" || $query[$cx] == "\n" || $query[$cx] == "\f")) $cx++;
|
3218 |
}
|
3219 |
|
3220 |
$state = "next_selector";
|
3257 |
return false;
|
3258 |
}
|
3259 |
}
|
3260 |
+
?>
|
includes/vendor/ultimate-web-scraper/websocket.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
// CubicleSoft PHP WebSocket class.
|
3 |
-
// (C)
|
4 |
|
5 |
// Implements RFC 6455 (WebSocket protocol).
|
6 |
// Requires the CubicleSoft PHP HTTP/HTTPS class.
|
@@ -463,14 +463,14 @@
|
|
463 |
{
|
464 |
if (strlen($this->readdata) < 2) return false;
|
465 |
|
466 |
-
$chr = ord($this->readdata
|
467 |
$fin = (($chr & 0x80) ? true : false);
|
468 |
$rsv1 = (($chr & 0x40) ? true : false);
|
469 |
$rsv2 = (($chr & 0x20) ? true : false);
|
470 |
$rsv3 = (($chr & 0x10) ? true : false);
|
471 |
$opcode = $chr & 0x0F;
|
472 |
|
473 |
-
$chr = ord($this->readdata
|
474 |
$mask = (($chr & 0x80) ? true : false);
|
475 |
$length = $chr & 0x7F;
|
476 |
if ($length == 126) $start = 4;
|
@@ -500,7 +500,7 @@
|
|
500 |
// Decode the payload.
|
501 |
for ($x = 0; $x < $length; $x++)
|
502 |
{
|
503 |
-
$payload
|
504 |
}
|
505 |
}
|
506 |
|
@@ -565,7 +565,7 @@
|
|
565 |
$y = strlen($payload);
|
566 |
for ($x = 0; $x < $y; $x++)
|
567 |
{
|
568 |
-
$payload
|
569 |
}
|
570 |
}
|
571 |
|
@@ -598,7 +598,7 @@
|
|
598 |
$result = 0;
|
599 |
for ($x = 0; $x < 8; $x++)
|
600 |
{
|
601 |
-
$result = ($result * 256) + ord($data
|
602 |
}
|
603 |
|
604 |
return $result;
|
1 |
<?php
|
2 |
// CubicleSoft PHP WebSocket class.
|
3 |
+
// (C) 2020 CubicleSoft. All Rights Reserved.
|
4 |
|
5 |
// Implements RFC 6455 (WebSocket protocol).
|
6 |
// Requires the CubicleSoft PHP HTTP/HTTPS class.
|
463 |
{
|
464 |
if (strlen($this->readdata) < 2) return false;
|
465 |
|
466 |
+
$chr = ord($this->readdata[0]);
|
467 |
$fin = (($chr & 0x80) ? true : false);
|
468 |
$rsv1 = (($chr & 0x40) ? true : false);
|
469 |
$rsv2 = (($chr & 0x20) ? true : false);
|
470 |
$rsv3 = (($chr & 0x10) ? true : false);
|
471 |
$opcode = $chr & 0x0F;
|
472 |
|
473 |
+
$chr = ord($this->readdata[1]);
|
474 |
$mask = (($chr & 0x80) ? true : false);
|
475 |
$length = $chr & 0x7F;
|
476 |
if ($length == 126) $start = 4;
|
500 |
// Decode the payload.
|
501 |
for ($x = 0; $x < $length; $x++)
|
502 |
{
|
503 |
+
$payload[$x] = chr(ord($payload[$x]) ^ ord($maskingkey[$x % 4]));
|
504 |
}
|
505 |
}
|
506 |
|
565 |
$y = strlen($payload);
|
566 |
for ($x = 0; $x < $y; $x++)
|
567 |
{
|
568 |
+
$payload[$x] = chr(ord($payload[$x]) ^ ord($maskingkey[$x % 4]));
|
569 |
}
|
570 |
}
|
571 |
|
598 |
$result = 0;
|
599 |
for ($x = 0; $x < 8; $x++)
|
600 |
{
|
601 |
+
$result = ($result * 256) + ord($data[$x]);
|
602 |
}
|
603 |
|
604 |
return $result;
|