is_html_response() ) {
return $html;
}
$dry_run = (bool) Helper::get( 'dry_run', false );
$filtered = preg_replace_callback(
'##is',
function ( $match ) use ( $dry_run ) {
return $this->process( $match, $dry_run );
},
$html
);
// A backtrack limit or a catastrophic pattern returns null. Serving the
// original page ungated is bad; serving an empty page is worse.
return null === $filtered ? $html : $filtered;
}
/**
* Decide what to do with one script element.
*
* @param array $match Regex match: 0 whole, 1 attributes, 2 contents.
* @param bool $dry_run Report instead of rewrite.
* @return string
*/
private function process( $match, $dry_run ) {
$whole = $match[0];
$attrs = $match[1];
$code = $match[2];
$open = '';
}
/**
* Whether this script would run if left alone.
*
* @param string $attrs Raw attribute string.
* @return bool
*/
private function is_executable( $attrs ) {
$type = strtolower( trim( (string) $this->attribute( $attrs, 'type' ) ) );
return in_array( $type, self::$executable_types, true );
}
/**
* Pull one attribute's value out of a raw attribute string.
*
* @param string $attrs Raw attribute string.
* @param string $name Attribute name.
* @return string
*/
private function attribute( $attrs, $name ) {
if ( preg_match( '/\s' . preg_quote( $name, '/' ) . '\s*=\s*("([^"]*)"|\'([^\']*)\'|([^\s>]+))/i', ' ' . $attrs, $found ) ) {
foreach ( [ 2, 3, 4 ] as $group ) {
if ( isset( $found[ $group ] ) && '' !== $found[ $group ] ) {
return $found[ $group ];
}
}
}
return '';
}
/**
* Only rewrite documents that are actually HTML. A plugin that hijacks the
* request to return XML or a file download still passes through this
* buffer, and must come out the other side untouched.
*
* @return bool
*/
private function is_html_response() {
foreach ( headers_list() as $header ) {
if ( 0 === stripos( $header, 'content-type:' ) ) {
return (bool) stripos( $header, 'text/html' );
}
}
// No explicit header means PHP's default, which is text/html.
return true;
}
}