Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions js/apbct-public-bundle.min.js

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions js/apbct-public-bundle_ext-protection.min.js

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions js/apbct-public-bundle_ext-protection_gathering.min.js

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions js/apbct-public-bundle_full-protection.min.js

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions js/apbct-public-bundle_full-protection_gathering.min.js

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions js/apbct-public-bundle_gathering.min.js

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions js/apbct-public-bundle_int-protection.min.js

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions js/apbct-public-bundle_int-protection_gathering.min.js

Large diffs are not rendered by default.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ function ($matches) {

$inner_content = isset($matches[2]) ? $matches[2] : '';

if ( $this->shortcodeContentContainsHtmlTags($inner_content) ) {
return isset($matches[0]) ? $matches[0] : '';
}

return $this->callback($atts, $inner_content, $this->public_name);
},
$content
Expand Down Expand Up @@ -195,6 +199,26 @@ protected function isShortcodeInsideHtmlTag($content)
return false;
}

/**
* Skip shortcode pairs whose inner content contains HTML tags.
*
* In buffer mode the lazy [tag]...[/tag] match can pair an opener in one
* fragment with a closer in another and swallow everything between them
* (comments, articles, any markup). A legitimate shortcode wraps text only.
*
* @param string $content Inner shortcode content.
*
* @return bool
*/
protected function shortcodeContentContainsHtmlTags($content)
{
if ( ! is_string($content) || $content === '' ) {
return false;
}

return (bool) preg_match('/<\/?[a-zA-Z][a-zA-Z0-9:-]*(?:\s[^<>]*)?>/', $content);
}

/**
* Determines whether a given character offset is located inside an HTML tag.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,20 @@ public function changeContentBeforeEncoderModify($content)
// Extract shortcode content to protect it from email encoding, supports sc attributes(!)
$shortcode_exist_pattern = sprintf('/(\[%s(?:\s[^\]]*)?\])([\s\S]*?)(\[\/%s\])/s', $this->public_name, $this->public_name);
$content = preg_replace_callback($shortcode_exist_pattern, function ($matches) {
$placeholder = $this->buildPlaceholder($this->shortcode_counter++);
if (isset($matches[1], $matches[2], $matches[3])) {
$prefix = $matches[1];
$entity = $matches[2];
$suffix = $matches[3];
$entity = Escape::escKsesPost($entity);
$this->shortcode_replacements[$placeholder] = $prefix . $entity . $suffix;
if ( ! isset($matches[1], $matches[2], $matches[3]) ) {
return isset($matches[0]) ? $matches[0] : '';
}

if ( $this->shortcodeContentContainsHtmlTags($matches[2]) ) {
return isset($matches[0]) ? $matches[0] : '';
}

$placeholder = $this->buildPlaceholder($this->shortcode_counter++);
$prefix = $matches[1];
$entity = Escape::escKsesPost($matches[2]);
$suffix = $matches[3];
$this->shortcode_replacements[$placeholder] = $prefix . $entity . $suffix;

return $placeholder;
}, $content);
return $content;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@ public function changeContentBeforeEncoderModify($content)
$pattern = '/\[apbct_skip_encoding\](.*?)\[\/apbct_skip_encoding\]/s';

return preg_replace_callback($pattern, function ($matches) {
if (isset($matches[1])) {
if ( isset($matches[1]) ) {
if ( $this->shortcodeContentContainsHtmlTags($matches[1]) ) {
return isset($matches[0]) ? $matches[0] : '';
}

return $this->createPlaceholder($matches[1]);
}

Expand Down Expand Up @@ -174,6 +178,10 @@ protected function processSkipEncodingShortcodes($content)

return preg_replace_callback($pattern, function ($matches) {
if ( isset($matches[1]) ) {
if ( $this->shortcodeContentContainsHtmlTags($matches[1]) ) {
return isset($matches[0]) ? $matches[0] : '';
}

return $this->callback([], $matches[1], '');
}
/** @psalm-suppress PossiblyUndefinedIntArrayOffset */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Cleantalk\ApbctWP\ContactsEncoder\Shortcodes;

use Cleantalk\ApbctWP\ContactsEncoder\Integrations\CEIntegrationCommentList;
use Cleantalk\Common\ContactsEncoder\Dto\Params;

/**
Expand All @@ -16,11 +15,6 @@ class ShortCodesService

public $shortcodes_registered = false;

/**
* @var CEIntegrationCommentList
*/
private $comment_list_integration;

/**
* @return void
*/
Expand Down Expand Up @@ -71,7 +65,6 @@ public function __construct(Params $params)
{
$this->encode = new EncodeContentSC($params);
$this->shortcode_to_exclude = new ExcludedEncodeContentSC();
$this->comment_list_integration = new CEIntegrationCommentList();
}

public function addActionsBeforeModify($hook, $priority = 1)
Expand Down Expand Up @@ -107,7 +100,6 @@ public function modifyBufferBefore($buffer)
{
$this->encode->resetShortcodeReplacements();
$this->shortcode_to_exclude->resetShortcodeReplacements();
$buffer = $this->comment_list_integration->protect($buffer);
$buffer = $this->shortcode_to_exclude->changeContentBeforeEncoderModify($buffer);

return $this->encode->changeContentBeforeEncoderModify($buffer);
Expand All @@ -128,14 +120,11 @@ public function modifyBufferAfter($buffer)

if ( $apbct->settings['data__email_decoder_buffer'] ) {
$buffer = $this->shortcode_to_exclude->finalizeBufferAfterEncoding($buffer);
$buffer = $this->comment_list_integration->restore($buffer);
$apbct->buffer = $buffer;

return $buffer;
}

$buffer = $this->shortcode_to_exclude->changeContentAfterEncoderModify($buffer);

return $this->comment_list_integration->restore($buffer);
return $this->shortcode_to_exclude->changeContentAfterEncoderModify($buffer);
}
}
40 changes: 28 additions & 12 deletions lib/Cleantalk/Common/ContactsEncoder/ContactsEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -888,11 +888,7 @@ private function replaceAriaLabelWithPlaceholder($matches)
*/
private function isSecureAriaLabelPlaceholderAvailable()
{
if ( function_exists('random_bytes') ) {
return true;
}

return function_exists('openssl_random_pseudo_bytes');
return function_exists('random_bytes') || function_exists('openssl_random_pseudo_bytes');
}

/**
Expand All @@ -902,22 +898,42 @@ private function isSecureAriaLabelPlaceholderAvailable()
*/
private function generateAriaLabelPlaceholder()
{
$bytes = $this->getSecureRandomBytes(16);
if ( !is_string($bytes) || strlen($bytes) !== 16 ) {
return null;
}

return '%%APBCT_ARIA_' . bin2hex($bytes) . '%%';
}

/**
* @param int $length
*
* @return string|null
*/
private function getSecureRandomBytes($length)
{
if ( !is_int($length) || $length < 1 ) {
return null;
}

if ( function_exists('random_bytes') ) {
try {
$bytes = random_bytes(16);
if ( is_string($bytes) && strlen($bytes) === 16 ) {
return '%%APBCT_ARIA_' . bin2hex($bytes) . '%%';
// phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.random_bytesFound
$bytes = random_bytes($length);
if ( strlen($bytes) === $length ) {
return $bytes;
}
} catch ( \Exception $e ) {
// fall through to openssl
// Fall through to OpenSSL.
}
}

if ( function_exists('openssl_random_pseudo_bytes') ) {
$crypto_strong = false;
$bytes = openssl_random_pseudo_bytes(16, $crypto_strong);
if ( $crypto_strong && is_string($bytes) && strlen($bytes) === 16 ) {
return '%%APBCT_ARIA_' . bin2hex($bytes) . '%%';
$bytes = openssl_random_pseudo_bytes($length, $crypto_strong);
if ( $crypto_strong && is_string($bytes) && strlen($bytes) === $length ) {
return $bytes;
}
}

Expand Down
Loading
Loading