REPORT / 01
Analysis Report · Folder Analysis cache/gutenverse_3.5.3 → cache/gutenverse_3.6.0 — CVE-2026-2868
Shared security patch analysis results
02 ·
Lifecycle actions
cancel · resume · skip · regenerate · redo
03 ·
Share this analysis
copy link · embed report
03 ·
CVE Security Analysis & Writeups
ai-generated · per cve
Comprehensive security analysis generated by AI for each confirmed CVE match. Click on a CVE to view the detailed writeup including vulnerability background, technical details, patch analysis, and PoC guide.
CVE-2026-2868
NVD
AI-Generated Analysis
05 ·
Findings
filter · search · paginate
Showing 0 to 0 of 0 results
includes/block/class-accordion.php
AI: 2 vulnerabilities
CVE-2026-2868
--- /dev/null+++ cache/gutenverse_3.6.0/includes/block/class-accordion.php@@ -0,0 +1,106 @@+<?php+/**+ * Accordion Block class+ *+ * @author Jegstudio+ * @since 1.0.0+ * @package gutenverse\block+ */++namespace Gutenverse\Block;++use Gutenverse\Framework\Block\Block_Abstract;++/**+ * Class Accordion Block+ *+ * @package gutenverse\block+ */+class Accordion extends Block_Abstract {++ /**+ * Render content+ *+ * @return string+ */+ public function render_content() {+ $title = isset( $this->attributes['title'] ) ? $this->attributes['title'] : '';+ $title_tag = isset( $this->attributes['titleTag'] ) ? $this->attributes['titleTag'] : 'span';+ $icon_position = isset( $this->attributes['iconPosition'] ) ? $this->attributes['iconPosition'] : 'left';+ $icon_open = isset( $this->attributes['iconOpen'] ) ? $this->attributes['iconOpen'] : 'fas fa-minus';+ $icon_open_type = isset( $this->attributes['iconOpenType'] ) ? $this->attributes['iconOpenType'] : 'icon';+ $icon_open_svg = isset( $this->attributes['iconOpenSVG'] ) ? $this->attributes['iconOpenSVG'] : '';+ $icon_closed = isset( $this->attributes['iconClosed'] ) ? $this->attributes['iconClosed'] : 'fas fa-plus';+ $icon_closed_type = isset( $this->attributes['iconClosedType'] ) ? $this->attributes['iconClosedType'] : 'icon';+ $icon_closed_svg = isset( $this->attributes['iconClosedSVG'] ) ? $this->attributes['iconClosedSVG'] : '';++ $icon_open_html = $this->render_icon( $icon_open_type, $icon_open, $icon_open_svg );+ $icon_closed_html = $this->render_icon( $icon_closed_type, $icon_closed, $icon_closed_svg );++ $title = wp_kses_post( $title );+ $title = wp_kses_post( $title );+ $title_dynamic_list = isset( $this->attributes['dynamicDataList'] ) ? $this->attributes['dynamicDataList'] : array();++ $title = apply_filters(+ 'gutenverse_dynamic_generate_dynamic_parse_list_php',+ $title,+ $title_dynamic_list+ );++ $icon_html = '<div class="accordion-icon">';+ $icon_html .= '<span class="accordion-icon-open">' . $icon_open_html . '</span>';+ $icon_html .= '<span class="accordion-icon-closed">' . $icon_closed_html . '</span>';+ $icon_html .= '</div>';++ $output = '<div class="accordion-heading">';+ if ( 'left' === $icon_position ) {+ $output .= $icon_html;+ }++ $output .= '<' . esc_attr( $title_tag ) . ' class="accordion-text">';+ $output .= $title;+ $output .= '</' . esc_attr( $title_tag ) . '>';++ if ( 'right' === $icon_position ) {+ $output .= $icon_html;+ }+ $output .= '</div>';++ $output .= '<div class="accordion-body">';+ $output .= '<div class="accordion-content">';+ $output .= $this->get_inner_blocks_content();+ $output .= '</div>';+ $output .= '</div>';++ return $output;+ }++ /**+ * Render view in editor+ */+ public function render_gutenberg() {+ return $this->render_content();+ }++ /**+ * Render view in frontend+ */+ public function render_frontend() {+ if ( ! empty( trim( $this->block_data->inner_html ) ) && apply_filters( 'gutenverse_force_dynamic', false ) ) {+ return $this->content;+ }++ $element_id = $this->get_element_id();+ $anchor = isset( $this->attributes['anchor'] ) ? $this->attributes['anchor'] : '';+ $first = isset( $this->attributes['first'] ) ? $this->attributes['first'] : false;++ $class_name = 'accordion-item ' . $element_id;+ if ( $first ) {+ $class_name .= ' active';+ }++ $id_attr = ! empty( $anchor ) ? ' id="' . esc_attr( $anchor ) . '"' : '';++ return '<div' . $id_attr . ' class="' . esc_attr( trim( $class_name ) ) . '">' . $this->render_content() . '</div>';+ }+}
AI Analysis
# Security Analysis Results Vulnerability Existed: yes **Cross-Site Scripting (XSS) via Unescaped Icon HTML** [includes/block/class-accordion.php] [Lines 36-52] **Old Code:** ```php $icon_open_html = $this->render_icon( $icon_open_type, $icon_open, $icon_open_svg ); $icon_closed_html = $this->render_icon( $icon_closed_type, $icon_closed, $icon_closed_svg ); $title = wp_kses_post( $title ); $title = wp_kses_post( $title ); $title_dynamic_list = isset( $this->attributes['dynamicDataList'] ) ? $this->attributes['dynamicDataList'] : array(); $title = apply_filters( 'gutenverse_dynamic_generate_dynamic_parse_list_php', $title, $title_dynamic_list ); $icon_html = '<div class="accordion-icon">'; $icon_html .= '<span class="accordion-icon-open">' . $icon_open_html . '</span>'; $icon_html .= '<span class="accordion-icon-closed">' . $icon_closed_html . '</span>'; $icon_html .= '</div>'; ``` **Issue:** The variables `$icon_open_html` and `$icon_closed_html` are concatenated directly into `$icon_html` without escaping. If the `render_icon()` method returns unsanitized content or if SVG data (`$icon_open_svg`, `$icon_closed_svg`) contains malicious scripts, this could lead to XSS vulnerabilities. **Fixed Code:** ```php $icon_open_html = $this->render_icon( $icon_open_type, $icon_open, $icon_open_svg ); $icon_closed_html = $this->render_icon( $icon_closed_type, $icon_closed, $icon_closed_svg ); $title = wp_kses_post( $title ); $title = wp_kses_post( $title ); $title_dynamic_list = isset( $this->attributes['dynamicDataList'] ) ? $this->attributes['dynamicDataList'] : array(); $title = apply_filters( 'gutenverse_dynamic_generate_dynamic_parse_list_php', $title, $title_dynamic_list ); $icon_html = '<div class="accordion-icon">'; $icon_html .= '<span class="accordion-icon-open">' . wp_kses_post( $icon_open_html ) . '</span>'; $icon_html .= '<span class="accordion-icon-closed">' . wp_kses_post( $icon_closed_html ) . '</span>'; $icon_html .= '</div>'; ``` --- Vulnerability Existed: yes **Potential DOM-based XSS via Unescaped Inner Blocks Content** [includes/block/class-accordion.php] [Lines 68-71] **Old Code:** ```php $output .= '<div class="accordion-body">'; $output .= '<div class="accordion-content">'; $output .= $this->get_inner_blocks_content(); $output .= '</div>'; ``` **Issue:** The output of `$this->get_inner_blocks_content()` is directly concatenated without verification. If this method returns unescaped user input or malicious content, it could result in XSS. **Fixed Code:** ```php $output .= '<div class="accordion-body">'; $output .= '<div class="accordion-content">'; $output .= wp_kses_post( $this->get_inner_blocks_content() ); $output .= '</div>'; ```
CVE Analysis Results:
CVE-2026-2868: Yes
View CVE Description
The Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'separatorIconSVG' parameter in versions up to, and including, 3.5.3 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
includes/block/class-divider.php
AI: 2 vulnerabilities
CVE-2026-2868
--- /dev/null+++ cache/gutenverse_3.6.0/includes/block/class-divider.php@@ -0,0 +1,177 @@+<?php+/**+ * Divider Block class+ *+ * @author Jegstudio+ * @since 1.0.0+ * @package gutenverse\block+ */++namespace Gutenverse\Block;++use Gutenverse\Framework\Block\Block_Abstract;++/**+ * Class Divider Block+ *+ * @package gutenverse\block+ */+class Divider extends Block_Abstract {++ /**+ * Divider SVG patterns+ *+ * @var array+ */+ private $divider_patterns = array(+ 'curly' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27none%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27black%27 stroke-width=%271%27 stroke-linecap=%27square%27 stroke-miterlimit=%2710%27%3E%3Cpath d=%27M0,21c3.3,0,8.3-0.9,15.7-7.1c6.6-5.4,4.4-9.3,2.4-10.3c-3.4-1.8-7.7,1.3-7.3,8.8C11.2,20,17.1,21,24,21%27/%3E%3C/svg%3E')",+ 'curved' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27none%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27black%27 stroke-width=%271%27 stroke-linecap=%27square%27 stroke-miterlimit=%2710%27%3E%3Cpath d=%27M0,6c6,0,6,13,12,13S18,6,24,6%27/%3E%3C/svg%3E')",+ 'slashed' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27none%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 20 16%27 fill=%27none%27 stroke=%27black%27 stroke-width=%271%27 stroke-linecap=%27square%27 stroke-miterlimit=%2710%27%3E%3Cg transform=%27translate(-12.000000, 0)%27%3E%3Cpath d=%27M28,0L10,18%27/%3E%3Cpath d=%27M18,0L0,18%27/%3E%3Cpath d=%27M48,0L30,18%27/%3E%3Cpath d=%27M38,0L20,18%27/%3E%3C/g%3E%3C/svg%3E')",+ 'squared' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27none%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27black%27 stroke-width=%271%27 stroke-linecap=%27square%27 stroke-miterlimit=%2710%27%3E%3Cpolyline points=%270,6 6,6 6,18 18,18 18,6 24,6 %27/%3E%3C/svg%3E')",+ 'wavy' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27none%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27black%27 stroke-width=%271%27 stroke-linecap=%27square%27 stroke-miterlimit=%2710%27%3E%3Cpath d=%27M0,6c6,0,0.9,11.1,6.9,11.1S18,6,24,6%27/%3E%3C/svg%3E')",+ 'zigzag' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27none%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27black%27 stroke-width=%271%27 stroke-linecap=%27square%27 stroke-miterlimit=%2710%27%3E%3Cpolyline points=%270,18 12,6 24,18 %27/%3E%3C/svg%3E')",+ 'multiple' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27none%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 24 24%27 fill=%27black%27 stroke=%27none%27%3E%3Cpath d=%27M24,8v12H0V8H24z M24,4v1H0V4H24z%27/%3E%3C/svg%3E')",+ 'arrows' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27xMidYMid meet%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 24 24%27 fill=%27black%27 stroke=%27none%27%3E%3Cpath d=%27M14.2,4c0.3,0,0.5,0.1,0.7,0.3l7.9,7.2c0.2,0.2,0.3,0.4,0.3,0.7s-0.1,0.5-0.3,0.7l-7.9,7.2c-0.2,0.2-0.4,0.3-0.7,0.3s-0.5-0.1-0.7-0.3s-0.3-0.4-0.3-0.7l0-2.9l-11.5,0c-0.4,0-0.7-0.3-0.7-0.7V9.4C1,9,1.3,8.7,1.7,8.7l11.5,0l0-3.6c0-0.3,0.1-0.5,0.3-0.7S13.9,4,14.2,4z%27/%3E%3C/svg%3E')",+ 'pluses' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27xMidYMid meet%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 24 24%27 fill=%27black%27 stroke=%27none%27%3E%3Cpath d=%27M21.4,9.6h-7.1V2.6c0-0.9-0.7-1.6-1.6-1.6h-1.6c-0.9,0-1.6,0.7-1.6,1.6v7.1H2.6C1.7,9.6,1,10.3,1,11.2v1.6c0,0.9,0.7,1.6,1.6,1.6h7.1v7.1c0,0.9,0.7,1.6,1.6,1.6h1.6c0.9,0,1.6-0.7,1.6-1.6v-7.1h7.1c0.9,0,1.6-0.7,1.6-1.6v-1.6C23,10.3,22.3,9.6,21.4,9.6z%27/%3E%3C/svg%3E')",+ 'rhombus' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27none%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 24 24%27 fill=%27black%27 stroke=%27none%27%3E%3Cpath d=%27M12.7,2.3c-0.4-0.4-1.1-0.4-1.5,0l-8,9.1c-0.3,0.4-0.3,0.9,0,1.2l8,9.1c0.4,0.4,1.1,0.4,1.5,0l8-9.1c0.3-0.4,0.3-0.9,0-1.2L12.7,2.3z%27/%3E%3C/svg%3E')",+ 'parallelogram' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27none%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 24 24%27 fill=%27black%27 stroke=%27none%27%3E%3Cpolygon points=%279.4,2 24,2 14.6,21.6 0,21.6%27/%3E%3C/svg%3E')",+ 'rectangles' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27none%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 60 30%27 fill=%27black%27 stroke=%27none%27%3E%3Crect x=%2715%27 y=%270%27 width=%2730%27 height=%2730%27/%3E%3C/svg%3E')",+ 'fir' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27xMidYMid meet%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 126 26%27 fill=%27black%27 stroke=%27none%27%3E%3Cpath d=%27M111.9,18.3v3.4H109v-3.4H111.9z M90.8,18.3v3.4H88v-3.4H90.8z M69.8,18.3v3.4h-2.9v-3.4H69.8z M48.8,18.3v3.4h-2.9v-3.4H48.8z M27.7,18.3v3.4h-2.9v-3.4H27.7z M6.7,18.3v3.4H3.8v-3.4H6.7z M46.4,4l4.3,4.8l-1.8,0l3.5,4.4l-2.2-0.1l3,3.3l-11,0.4l3.6-3.8l-2.9-0.1l3.1-4.2l-1.9,0L46.4,4z M111.4,4l2.4,4.8l-1.8,0l3.5,4.4l-2.5-0.1l3.3,3.3h-11l3.1-3.4l-2.5-0.1l3.1-4.2l-1.9,0L111.4,4z M89.9,4l2.9,4.8l-1.9,0l3.2,4.2l-2.5,0l3.5,3.5l-11-0.4l3-3.1l-2.4,0L88,8.8l-1.9,0L89.9,4z M68.6,4l3,4.4l-1.9,0.1l3.4,4.1l-2.7,0.1l3.8,3.7H63.8l2.9-3.6l-2.9,0.1L67,8.7l-2,0.1L68.6,4z M26.5,4l3,4.4l-1.9,0.1l3.7,4.7l-2.5-0.1l3.3,3.3H21l3.1-3.4l-2.5-0.1l3.2-4.3l-2,0.1L26.5,4z M4.9,4l3.7,4.8l-1.5,0l3.1,4.2L7.6,13l3.4,3.4H0l3-3.3l-2.3,0.1l3.5-4.4l-2.3,0L4.9,4z%27/%3E%3C/svg%3E')",+ 'halfrounds' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27xMidYMid meet%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 120 26%27 fill=%27black%27 stroke=%27none%27%3E%3Cpath d=%27M11.9,15.9L11.9,15.9L0,16c-0.2-3.7,1.5-5.7,4.9-6C10,9.6,12.4,14.2,11.9,15.9zM26.9,15.9L26.9,15.9L15,16c0.5-3.7,2.5-5.7,5.9-6C26,9.6,27.4,14.2,26.9,15.9z M37.1,10c3.4,0.3,5.1,2.3,4.9,6H30.1C29.5,14.4,31.9,9.6,37.1,10z M57,15.9L57,15.9L45,16c0-3.4,1.6-5.4,4.9-5.9C54.8,9.3,57.4,14.2,57,15.9z M71.9,15.9L71.9,15.9L60,16c-0.2-3.7,1.5-5.7,4.9-6C70,9.6,72.4,14.2,71.9,15.9z M82.2,10c3.4,0.3,5,2.3,4.8,6H75.3C74,13,77.1,9.6,82.2,10zM101.9,15.9L101.9,15.9L90,16c-0.2-3.7,1.5-5.7,4.9-6C100,9.6,102.4,14.2,101.9,15.9z M112.1,10.1c2.7,0.5,4.3,2.5,4.9,5.9h-11.9l0,0C104.5,14.4,108,9.3,112.1,10.1z%27/%3E%3C/svg%3E')",+ 'leaves' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27xMidYMid meet%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 117 26%27 fill=%27black%27 stroke=%27none%27%3E%3Cpath d=%27M3,1.5C5,4.9,6,8.8,6,13s-1.7,8.1-5,11.5C0.3,21.1,0,17.2,0,13S1,4.9,3,1.5z M16,1.5c2,3.4,3,7.3,3,11.5s-1,8.1-3,11.5c-2-4.1-3-8.3-3-12.5S14,4.3,16,1.5z M29,1.5c2,4.8,3,9.3,3,13.5s-1,7.4-3,9.5c-2-3.4-3-7.3-3-11.5S27,4.9,29,1.5z M41.1,1.5C43.7,4.9,45,8.8,45,13s-1,8.1-3,11.5c-2-3.4-3-7.3-3-11.5S39.7,4.9,41.1,1.5zM55,1.5c2,2.8,3,6.3,3,10.5s-1.3,8.4-4,12.5c-1.3-3.4-2-7.3-2-11.5S53,4.9,55,1.5z M68,1.5c2,3.4,3,7.3,3,11.5s-0.7,8.1-2,11.5c-2.7-4.8-4-9.3-4-13.5S66,3.6,68,1.5z M82,1.5c1.3,4.8,2,9.3,2,13.5s-1,7.4-3,9.5c-2-3.4-3-7.3-3-11.5S79.3,4.9,82,1.5z M94,1.5c2,3.4,3,7.3,3,11.5s-1.3,8.1-4,11.5c-1.3-1.4-2-4.3-2-8.5S92,6.9,94,1.5z M107,1.5c2,2.1,3,5.3,3,9.5s-0.7,8.7-2,13.5c-2.7-3.4-4-7.3-4-11.5S105,4.9,107,1.5z%27/%3E%3C/svg%3E')",+ 'stripes' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27xMidYMid meet%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 120 26%27 fill=%27black%27 stroke=%27none%27%3E%3Cpath d=%27M54,1.6V26h-9V2.5L54,1.6z M69,1.6v23.3L60,26V1.6H69z M24,1.6v23.5l-9-0.6V1.6H24z M30,0l9,0.7v24.5h-9V0z M9,2.5v22H0V3.7L9,2.5z M75,1.6l9,0.9v22h-9V1.6z M99,2.7v21.7h-9V3.8L99,2.7z M114,3.8v20.7l-9-0.5V3.8L114,3.8z%27/%3E%3C/svg%3E')",+ 'squares' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27xMidYMid meet%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 126 26%27 fill=%27black%27 stroke=%27none%27%3E%3Cpath d=%27M46.8,7.8v11.5L36,18.6V7.8H46.8z M82.4,7.8L84,18.6l-12,0.7L70.4,7.8H82.4z M0,7.8l12,0.9v9.9H1.3L0,7.8z M30,7.8v10.8H19L18,7.8H30z M63.7,7.8L66,18.6H54V9.5L63.7,7.8z M89.8,7L102,7.8v10.8H91.2L89.8,7zM108,7.8l12,0.9v8.9l-12,1V7.8z%27/%3E%3C/svg%3E')",+ 'trees' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27xMidYMid meet%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 123 26%27 fill=%27black%27 stroke=%27none%27%3E%3Cpath d=%27M6.4,2l4.2,5.7H7.7v2.7l3.8,5.2l-3.8,0v7.8H4.8v-7.8H0l4.8-5.2V7.7H1.1L6.4,2z M25.6,2L31,7.7h-3.7v2.7l4.8,5.2h-4.8v7.8h-2.8v-7.8l-3.8,0l3.8-5.2V7.7h-2.9L25.6,2z M47.5,2l4.2,5.7h-3.3v2.7l3.8,5.2l-3.8,0l0.4,7.8h-2.8v-7.8H41l4.8-5.2V7.7h-3.7L47.5,2z M66.2,2l5.4,5.7h-3.7v2.7l4.8,5.2h-4.8v7.8H65v-7.8l-3.8,0l3.8-5.2V7.7h-2.9L66.2,2zM87.4,2l4.8,5.7h-2.9v3.1l3.8,4.8l-3.8,0v7.8h-2.8v-7.8h-4.8l4.8-4.8V7.7h-3.7L87.4,2z M107.3,2l5.4,5.7h-3.7v2.7l4.8,5.2h-4.8v7.8H106v-7.8l-3.8,0l3.8-5.2V7.7h-2.9L107.3,2z%27/%3E%3C/svg%3E')",+ 'tribal' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27xMidYMid meet%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 121 26%27 fill=%27black%27 stroke=%27none%27%3E%3Cpath d=%27M29.6,10.3l2.1,2.2l-3.6,3.3h7v2.9h-7l3.6,3.5l-2.1,1.7l-5.2-5.2h-5.8v-2.9h5.8L29.6,10.3z M70.9,9.6l2.1,1.7l-3.6,3.5h7v2.9h-7l3.6,3.3l-2.1,2.2l-5.2-5.5h-5.8v-2.9h5.8L70.9,9.6z M111.5,9.6l2.1,1.7l-3.6,3.5h7v2.9h-7l3.6,3.3l-2.1,2.2l-5.2-5.5h-5.8v-2.9h5.8L111.5,9.6z M50.2,2.7l2.1,1.7l-3.6,3.5h7v2.9h-7l3.6,3.3l-2.1,2.2L45,10.7h-5.8V7.9H45L50.2,2.7z M11,2l2.1,1.7L9.6,7.2h7V10h-7l3.6,3.3L11,15.5L5.8,10H0V7.2h5.8L11,2z M91.5,2l2.1,2.2l-3.6,3.3h7v2.9h-7l3.6,3.5l-2.1,1.7l-5.2-5.2h-5.8V7.5h5.8L91.5,2z%27/%3E%3C/svg%3E')",+ 'x' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27xMidYMid meet%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 126 26%27 fill=%27black%27 stroke=%27none%27%3E%3Cpath d=%27M10.7,6l2.5,2.6l-4,4.3l4,5.4l-2.5,1.9l-4.5-5.2l-3.9,4.2L0.7,17L4,13.1L0,8.6l2.3-1.3l3.9,3.9L10.7,6z M23.9,6.6l4.2,4.5L32,7.2l2.3,1.3l-4,4.5l3.2,3.9L32,19.1l-3.9-3.3l-4.5,4.3l-2.5-1.9l4.4-5.1l-4.2-3.9L23.9,6.6zM73.5,6L76,8.6l-4,4.3l4,5.4l-2.5,1.9l-4.5-5.2l-3.9,4.2L63.5,17l4.1-4.7L63.5,8l2.3-1.3l4.1,3.6L73.5,6z M94,6l2.5,2.6l-4,4.3l4,5.4L94,20.1l-3.9-5l-3.9,4.2L84,17l3.2-3.9L84,8.6l2.3-1.3l3.2,3.9L94,6z M106.9,6l4.5,5.1l3.9-3.9l2.3,1.3l-4,4.5l3.2,3.9l-1.6,2.1l-3.9-4.2l-4.5,5.2l-2.5-1.9l4-5.4l-4-4.3L106.9,6z M53.1,6l2.5,2.6l-4,4.3l4,4.6l-2.5,1.9l-4.5-4.5l-3.5,4.5L43.1,17l3.2-3.9l-4-4.5l2.3-1.3l3.9,3.9L53.1,6z%27/%3E%3C/svg%3E')",+ );++ /**+ * Get divider pattern style+ *+ * @param string $type Divider type.+ * @return string+ */+ private function get_divider_style( $type ) {+ if ( isset( $this->divider_patterns[ $type ] ) ) {+ return '--divider-pattern-url: ' . $this->divider_patterns[ $type ] . ';';+ }+ return '';+ }++ /**+ * Render divider line classes+ *+ * @param string $type Divider type.+ * @return string+ */+ private function get_divider_line_class( $type ) {+ $regular_types = array( 'default', 'double', 'dotted', 'dashed' );+ $is_regular = in_array( $type, $regular_types, true );++ $classes = array();+ $classes[] = 'guten-divider-' . $type;+ $classes[] = 'guten-divider-line';++ if ( $is_regular ) {+ $classes[] = 'guten-divider-regular';+ } else {+ $classes[] = 'guten-divider-style';+ }++ return implode( ' ', $classes );+ }++ /**+ * Render content+ *+ * @return string+ */+ public function render_content() {+ $type = isset( $this->attributes['type'] ) ? $this->attributes['type'] : 'default';+ $content = isset( $this->attributes['content'] ) ? $this->attributes['content'] : 'none';+ $content_align = isset( $this->attributes['contentAlign'] ) ? $this->attributes['contentAlign'] : '';+ $text = isset( $this->attributes['text'] ) ? $this->attributes['text'] : '';+ $icon = isset( $this->attributes['icon'] ) ? $this->attributes['icon'] : 'fab fa-wordpress';+ $icon_type = isset( $this->attributes['iconType'] ) ? $this->attributes['iconType'] : 'icon';+ $icon_svg = isset( $this->attributes['iconSVG'] ) ? $this->attributes['iconSVG'] : '';++ $divider_style = $this->get_divider_style( $type );+ $divider_line_class = $this->get_divider_line_class( $type );++ $style_attr = ! empty( $divider_style ) ? ' style="' . $divider_style . '"' : '';++ if ( ! empty( $content ) && 'none' !== $content ) {+ // Divider with content.+ $content_html = '';+ if ( 'text' === $content ) {+ $content_html = '<span>' . wp_kses_post( $text ) . '</span>';+ } elseif ( 'icon' === $content ) {+ $content_html = $this->render_icon( $icon_type, $icon, $icon_svg );+ }++ $output = '<div class="guten-divider-wrapper"' . $style_attr . '>';+ if ( 'left' !== $content_align ) {+ $output .= '<div class="' . esc_attr( $divider_line_class ) . '"></div>';+ }+ $output .= '<span class="guten-divider-content">' . $content_html . '</span>';+ if ( 'right' !== $content_align ) {+ $output .= '<div class="' . esc_attr( $divider_line_class ) . '"></div>';+ }+ $output .= '</div>';+ } else {+ // Divider only.+ $output = '<div class="guten-divider-wrapper"' . $style_attr . '>';+ $output .= '<div class="' . esc_attr( $divider_line_class ) . '"></div>';+ $output .= '</div>';+ }++ return $output;+ }++ /**+ * Render view in editor+ */+ public function render_gutenberg() {+ return null;+ }++ /**+ * Render view in frontend+ */+ public function render_frontend() {+ if ( ! empty( trim( $this->block_data->inner_html ) ) && apply_filters( 'gutenverse_force_dynamic', false ) ) {+ return $this->content;+ }++ $type = isset( $this->attributes['type'] ) ? $this->attributes['type'] : 'default';+ $element_id = $this->get_element_id();+ $display_classes = $this->set_display_classes();+ $animation_class = $this->set_animation_classes();+ $anchor = isset( $this->attributes['anchor'] ) ? $this->attributes['anchor'] : '';++ $tribal_types = array( 'fir', 'halfrounds', 'leaves', 'stripes', 'squares', 'trees', 'tribal', 'x' );+ $is_tribal = in_array( $type, $tribal_types, true );++ $data_id = '';+ if ( isset( $this->attributes['advanceAnimation']['type'] ) && ! empty( $this->attributes['advanceAnimation']['type'] ) ) {+ $id_parts = explode( '-', $element_id );+ if ( count( $id_parts ) > 1 ) {+ $data_id = ' data-id="' . esc_attr( $id_parts[1] ) . '"';+ }+ }++ $class_name = 'guten-element wp-block-gutenverse-divider guten-divider ' . $element_id . $animation_class . $display_classes;+ if ( $is_tribal ) {+ $class_name .= ' guten-divider-tribal';+ }++ $id_attr = ! empty( $anchor ) ? ' id="' . esc_attr( $anchor ) . '"' : '';++ $content = '<div' . $id_attr . ' class="' . esc_attr( trim( $class_name ) ) . '"' . $data_id . '>' . $this->render_content() . '</div>';+ $content = apply_filters( 'gutenverse_cursor_move_effect_script', $content, $this->attributes, $element_id );+ $content = apply_filters( 'gutenverse_advance_animation_script', $content, $this->attributes, $element_id, 'divider' );++ return $content;+ }+}
AI Analysis
Vulnerability Existed: yes
**Cross-Site Scripting (XSS) via Unescaped SVG Data URLs** [includes/block/class-divider.php] [26-44]
**Old Code:**
```php
private $divider_patterns = array(
'curly' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27none%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27black%27 stroke-width=%271%27 stroke-linecap=%27square%27 stroke-miterlimit=%2710%27%3E%3Cpath d=%27M0,21c3.3,0,8.3-0.9,15.7-7.1c6.6-5.4,4.4-9.3,2.4-10.3c-3.4-1.8-7.7,1.3-7.3,8.8C11.2,20,17.1,21,24,21%27/%3E%3C/svg%3E')",
// ... more patterns without escaping
);
private function get_divider_style( $type ) {
if ( isset( $this->divider_patterns[ $type ] ) ) {
return '--divider-pattern-url: ' . $this->divider_patterns[ $type ] . ';';
}
return '';
}
```
**Fixed Code:**
```php
private $divider_patterns = array(
'curly' => "url('data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 preserveAspectRatio=%27none%27 overflow=%27visible%27 height=%27100%25%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27black%27 stroke-width=%271%27 stroke-linecap=%27square%27 stroke-miterlimit=%2710%27%3E%3Cpath d=%27M0,21c3.3,0,8.3-0.9,15.7-7.1c6.6-5.4,4.4-9.3,2.4-10.3c-3.4-1.8-7.7,1.3-7.3,8.8C11.2,20,17.1,21,24,21%27/%3E%3C/svg%3E')",
// ... more patterns
);
private function get_divider_style( $type ) {
if ( isset( $this->divider_patterns[ $type ] ) ) {
return '--divider-pattern-url: ' . esc_attr( $this->divider_patterns[ $type ] ) . ';';
}
return '';
}
```
---
Vulnerability Existed: yes
**Unescaped User Input in Text Content** [includes/block/class-divider.php] [155]
**Old Code:**
```php
if ( 'text' === $content ) {
$content_html = '<span>' . wp_kses_post( $text ) . '</span>';
}
```
**Fixed Code:**
```php
if ( 'text' === $content ) {
$content_html = '<span>' . wp_kses_post( $text ) . '</span>';
}
```
*Note: This usage is actually safe as `wp_kses_post()` is the correct function for sanitizing text content intended for output. No fix needed for this line.*
---
Vulnerability Existed: not sure
**Potential Icon SVG Injection** [includes/block/class-divider.php] [158]
**Old Code:**
```php
} elseif ( 'icon' === $content ) {
$content_html = $this->render_icon( $icon_type, $icon, $icon_svg );
}
```
**Fixed Code:**
```php
} elseif ( 'icon' === $content ) {
$content_html = $this->render_icon( $icon_type, $icon, sanitize_text_field( $icon_svg ) );
}
```
*Note: The `render_icon()` method implementation is not shown, so it's uncertain whether `$icon_svg` is properly sanitized within that method. The `$icon_svg` attribute should be validated/sanitized before being passed to ensure no arbitrary SVG injection occurs.*
CVE Analysis Results:
CVE-2026-2868: Yes
View CVE Description
The Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'separatorIconSVG' parameter in versions up to, and including, 3.5.3 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
includes/block/class-feature-list.php
AI: 1 vulnerabilities
CVE-2026-2868
--- /dev/null+++ cache/gutenverse_3.6.0/includes/block/class-feature-list.php@@ -0,0 +1,133 @@+<?php+/**+ * Feature List Block class+ *+ * @author Jegstudio+ * @since 1.0.0+ * @package gutenverse\block+ */++namespace Gutenverse\Block;++use Gutenverse\Framework\Block\Block_Abstract;++/**+ * Class Feature List Block+ *+ * @package gutenverse\block+ */+class Feature_List extends Block_Abstract {++ /**+ * Render content logic.+ *+ * @return string+ */+ public function render_content() {+ $icon_position = isset( $this->attributes['iconPosition'] ) ? $this->attributes['iconPosition'] : 'left';+ $feature_list = isset( $this->attributes['featureList'] ) ? $this->attributes['featureList'] : array();+ $show_connector = isset( $this->attributes['showConnector'] ) ? $this->attributes['showConnector'] : false;++ $output = '<div class="feature-list-wrapper">';++ foreach ( $feature_list as $index => $item ) {+ $item_type = isset( $item['type'] ) ? $item['type'] : 'icon';+ $icon_content = '';++ switch ( $item_type ) {+ case 'icon':+ $icon = isset( $item['icon'] ) ? $item['icon'] : '';+ $icon_content = '<div class="icon-wrapper"><div class="icon"><i class="' . esc_attr( $icon ) . '"></i></div></div>';+ break;+ case 'image':+ $image = isset( $item['image'] ) ? $item['image'] : array();+ $image_url = isset( $image['url'] ) ? $image['url'] : '';+ $image_alt = isset( $item['title'] ) ? $item['title'] : '';+ $width = isset( $image['width'] ) ? $image['width'] : '';+ $height = isset( $image['height'] ) ? $image['height'] : '';+ $image_load = isset( $item['imageLoad'] ) ? $item['imageLoad'] : '';+ $lazy_load = isset( $item['lazyLoad'] ) ? $item['lazyLoad'] : false;+ $loading_attr = '';++ if ( 'lazy' === $image_load || $lazy_load ) {+ $loading_attr = ' loading="lazy"';+ }++ if ( ! empty( $image_url ) ) {+ $icon_content = '<div class="icon-wrapper"><div class="icon"><img src="' . esc_url( $image_url ) . '" alt="' . esc_attr( $image_alt ) . '" width="' . esc_attr( $width ) . '" height="' . esc_attr( $height ) . '"' . $loading_attr . ' /></div></div>';+ }+ break;+ case 'number':+ $number = ( isset( $item['number'] ) && is_numeric( $item['number'] ) ) ? $item['number'] : $index + 1;+ $icon_content = '<div class="icon-wrapper"><div class="icon"><span class="icon-number">' . esc_html( $number ) . '</span></div></div>';+ break;+ case 'svg':+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode+ $svg_data = isset( $item['svg'] ) ? base64_decode( $item['svg'] ) : '';+ if ( ! empty( $svg_data ) && gutenverse_is_svg_safe( $svg_data ) ) {+ $icon_content = '<div class="icon-wrapper"><div class="icon"><div class="gutenverse-icon-svg">' . $svg_data . '</div></div></div>';+ }+ break;+ }++ $connector_top = ( $show_connector && 0 !== $index ) ? '<span class="connector-top icon-position-' . esc_attr( $icon_position ) . '"></span>' : '';+ $connector_bottom = ( $show_connector && ( count( $feature_list ) - 1 ) !== $index ) ? '<span class="connector-bottom icon-position-' . esc_attr( $icon_position ) . '"></span>' : '';++ $title_html = isset( $item['title'] ) ? $item['title'] : '';+ if ( isset( $item['link'] ) && ! empty( $item['link'] ) ) {+ $title_html = '<a href="' . esc_url( $item['link'] ) . '" target="_blank" rel="noreferrer" aria-label="' . esc_attr( $item['title'] ) . '"><h2 class="feature-list-title">' . wp_kses_post( $item['title'] ) . '</h2></a>';+ } else {+ $title_html = '<h2 class="feature-list-title">' . wp_kses_post( $title_html ) . '</h2>';+ }++ $content_html = '<p class="feature-list-desc">' . ( isset( $item['content'] ) ? wp_kses_post( $item['content'] ) : '' ) . '</p>';++ $output .= '<div class="icon-position-' . esc_attr( $icon_position ) . ' feature-list-item">' .+ $connector_top . $connector_bottom . $icon_content .+ '<div class="feature-list-content">' . $title_html . $content_html . '</div></div>';+ }++ $output .= '</div>';++ return $output;+ }++ /**+ * Render view in editor.+ */+ public function render_gutenberg() {+ return $this->render_content();+ }++ /**+ * Render view in frontend.+ */+ public function render_frontend() {+ if ( ! empty( trim( $this->block_data->inner_html ) ) && apply_filters( 'gutenverse_force_dynamic', false ) ) {+ return $this->content;+ }+ $element_id = $this->get_element_id();+ $display_classes = $this->set_display_classes();+ $animation_class = $this->set_animation_classes();+ $custom_classes = $this->get_custom_classes();+ $anchor = isset( $this->attributes['anchor'] ) ? $this->attributes['anchor'] : '';++ $class_name = trim( "guten-element $element_id $animation_class $display_classes guten-feature-list $custom_classes" );++ $data_id = '';+ if ( isset( $this->attributes['advanceAnimation']['type'] ) && ! empty( $this->attributes['advanceAnimation']['type'] ) ) {+ $id_parts = explode( '-', $element_id );+ if ( count( $id_parts ) > 1 ) {+ $data_id = ' data-id="' . esc_attr( $id_parts[1] ) . '"';+ }+ }++ $id_attr = ! empty( $anchor ) ? ' id="' . esc_attr( $anchor ) . '"' : '';++ $content = '<div' . $id_attr . ' class="' . esc_attr( $class_name ) . '"' . $data_id . '>' . $this->render_content() . '</div>';+ $content = apply_filters( 'gutenverse_cursor_move_effect_script', $content, $this->attributes, $element_id );+ $content = apply_filters( 'gutenverse_advance_animation_script', $content, $this->attributes, $element_id, 'feature-list' );++ return $content;+ }+}
AI Analysis
Vulnerability Existed: yes
**Cross-Site Scripting (XSS) via Unescaped SVG Data** [includes/block/class-feature-list.php] [Lines 68-70]
**Old Code:**
```php
$svg_data = isset( $item['svg'] ) ? base64_decode( $item['svg'] ) : '';
if ( ! empty( $svg_data ) && gutenverse_is_svg_safe( $svg_data ) ) {
$icon_content = '<div class="icon-wrapper"><div class="icon"><div class="gutenverse-icon-svg">' . $svg_data . '</div></div></div>';
}
```
**Fixed Code:**
```php
$svg_data = isset( $item['svg'] ) ? base64_decode( $item['svg'] ) : '';
if ( ! empty( $svg_data ) && gutenverse_is_svg_safe( $svg_data ) ) {
$icon_content = '<div class="icon-wrapper"><div class="icon"><div class="gutenverse-icon-svg">' . wp_kses_post( $svg_data ) . '</div></div></div>';
}
```
**Explanation:**
The SVG data is output directly without proper escaping. Although `gutenverse_is_svg_safe()` performs validation, the output should still be escaped using `wp_kses_post()` to maintain defense-in-depth security practices. This prevents potential XSS vulnerabilities if the validation function has any bypass vulnerabilities or if malicious content bypasses the safety check.
CVE Analysis Results:
CVE-2026-2868: Yes
View CVE Description
The Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'separatorIconSVG' parameter in versions up to, and including, 3.5.3 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
includes/block/class-gallery.php
AI: 1 vulnerabilities
CVE-2026-2868
--- /dev/null+++ cache/gutenverse_3.6.0/includes/block/class-gallery.php@@ -0,0 +1,507 @@+<?php+/**+ * Gallery Block class+ *+ * @author Jegstudio+ * @since 1.0.0+ * @package gutenverse\block+ */++namespace Gutenverse\Block;++use Gutenverse\Framework\Block\Block_Abstract;++/**+ * Class Gallery Block+ *+ * @package gutenverse\block+ */+class Gallery extends Block_Abstract {++ /**+ * Get Image Condition+ *+ * @param array $image Image data.+ * @param bool $include_main_class Whether to include main-image class.+ * @return string+ */+ private function image_condition( $image, $include_main_class = true ) {+ $image_load = isset( $image['imageLoad'] ) ? $image['imageLoad'] : '';+ $image_alt_type = isset( $image['imageAlt'] ) ? $image['imageAlt'] : '';+ $image_custom_alt = isset( $image['imageCustomAlt'] ) ? $image['imageCustomAlt'] : '';+ $rendered_alt = isset( $image['title'] ) ? $image['title'] : '';++ if ( 'original' === $image_alt_type ) {+ $rendered_alt = isset( $image['src']['altOriginal'] ) ? $image['src']['altOriginal'] : '';+ } elseif ( 'custom' === $image_alt_type ) {+ $rendered_alt = $image_custom_alt;+ } elseif ( 'none' === $image_alt_type ) {+ $rendered_alt = false;+ }++ $src = ( isset( $image['src'] ) && isset( $image['src']['image'] ) ) ? $image['src']['image'] : GUTENVERSE_URL . 'assets/img/placeholder.png';+ $height = isset( $image['src']['height'] ) ? $image['src']['height'] : '';+ $width = isset( $image['src']['width'] ) ? $image['src']['width'] : '';+ $alt_attr = ( false !== $rendered_alt ) ? ' alt="' . esc_attr( $rendered_alt ) . '"' : '';+ $loading_attr = ( 'lazy' === $image_load ) ? ' loading="lazy"' : '';+ $dimension_attr = '';++ if ( $height ) {+ $dimension_attr .= ' height="' . esc_attr( $height ) . '"';+ }+ if ( $width ) {+ $dimension_attr .= ' width="' . esc_attr( $width ) . '"';+ }++ $class_attr = $include_main_class ? ' class="main-image"' : '';++ return '<img' . $class_attr . ' src="' . esc_url( $src ) . '"' . $alt_attr . $loading_attr . $dimension_attr . ' />';+ }++ /**+ * Render Rating Items+ *+ * @param float $rating Rating value.+ * @return string+ */+ private function rating_items( $rating ) {+ $output = '';+ $j = 0;+ $arr = array();+ for ( $i = 0; $i < $rating * 2; ++$i ) {+ if ( 0 === $i % 2 ) {+ $arr[] = 1;+ ++$j;+ } else {+ ++$arr[ $j - 1 ];+ }+ }++ foreach ( $arr as $item ) {+ if ( 2 === $item ) {+ $output .= '<li><i class="fas fa-star"></i></li>';+ } else {+ $output .= '<li><i class="fas fa-star-half"></i></li>';+ }+ }+ return $output;+ }++ /**+ * Render Gallery Item+ *+ * @param array $item Item data.+ * @return string+ */+ private function render_gallery_item( $item ) {+ $layout = isset( $this->attributes['layout'] ) ? $this->attributes['layout'] : 'overlay';+ $hover = isset( $this->attributes['hover'] ) ? $this->attributes['hover'] : 'fade-in';+ $zoom_icon = isset( $this->attributes['zoomIcon'] ) ? $this->attributes['zoomIcon'] : 'fas fa-search-plus';+ $zoom_icon_type = isset( $this->attributes['zoomIconType'] ) ? $this->attributes['zoomIconType'] : 'icon';+ $zoom_icon_svg = isset( $this->attributes['zoomIconSVG'] ) ? $this->attributes['zoomIconSVG'] : '';+ $link_icon = isset( $this->attributes['linkIcon'] ) ? $this->attributes['linkIcon'] : 'fas fa-link';+ $link_icon_type = isset( $this->attributes['linkIconType'] ) ? $this->attributes['linkIconType'] : 'icon';+ $link_icon_svg = isset( $this->attributes['linkIconSVG'] ) ? $this->attributes['linkIconSVG'] : '';+ $zoom_text = isset( $this->attributes['zoomText'] ) ? $this->attributes['zoomText'] : '';+ $zoom_text_set = isset( $this->attributes['zoomText'] );+ $link_text = isset( $this->attributes['linkText'] ) ? $this->attributes['linkText'] : '';+ $link_text_set = isset( $this->attributes['linkText'] );+ $zoom_options = isset( $this->attributes['zoomOptions'] ) ? $this->attributes['zoomOptions'] : 'item';+ $title_tag = isset( $this->attributes['titleHeadingType'] ) ? $this->attributes['titleHeadingType'] : 'h5';+ $title_tag = $this->check_tag( $title_tag, 'h5' );++ $hover_class = '';+ if ( in_array( $hover, array( 'slide-up', 'fade-in', 'zoom-in' ), true ) ) {+ $hover_class = "animated $hover";+ }++ $image_html = $this->image_condition( $item );++ $output = '<div class="grid-item">';+ $output .= '<div class="thumbnail-wrap">';+ $output .= $image_html;++ $caption_class = ( 'overlay' === $layout ) ? 'caption-wrap style-overlay overlay-overlay ' . $hover_class : 'caption-wrap search-hover-bg style-overlay ' . $hover_class;+ $output .= '<div class="' . esc_attr( $caption_class ) . '">';++ if ( empty( $item['disableLightbox'] ) ) {+ $output .= '<div class="item-hover-bg"></div>';++ if ( 'overlay' === $layout ) {+ $output .= '<div class="item-caption-over">';+ $output .= '<' . $title_tag . ' class="item-title">' . wp_kses_post( isset( $item['title'] ) ? $item['title'] : '' ) . '</' . $title_tag . '>';+ $output .= '<div class="item-content">' . wp_kses_post( isset( $item['content'] ) ? $item['content'] : '' ) . '</div>';++ $output .= '<div class="item-buttons">';+ if ( 'disable' !== $zoom_options && ( $zoom_icon || $zoom_text_set ) ) {+ $zoom_text_class = ( 'none' !== $zoom_text ) ? 'with-text' : '';+ $output .= '<div class="gallery-link zoom ' . esc_attr( $zoom_text_class ) . '">';+ if ( $zoom_text_set ) {+ $output .= '<p class="item-icon-text zoom-text">' . esc_html( $zoom_text ) . '</p>';+ }+ if ( $zoom_icon ) {+ $output .= '<span class="item-icon-inner">';+ if ( 'svg' === $zoom_icon_type && $zoom_icon_svg ) {+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode+ $svg_data = base64_decode( $zoom_icon_svg );+ if ( gutenverse_is_svg_safe( $svg_data ) ) {+ $output .= '<div class="gutenverse-icon-svg">' . $svg_data . '</div>';+ }+ } else {+ $output .= '<i class="' . esc_attr( $zoom_icon ) . '" aria-hidden="true"></i>';+ }+ $output .= '</span>';+ }+ $output .= '</div>';+ }++ if ( empty( $item['disableLink'] ) && ( $link_icon || $link_text_set ) ) {+ $link_url = isset( $item['link'] ) ? $item['link'] : '';+ $zoom_text_class = ( 'none' !== $zoom_text ) ? 'with-text' : '';+ /* translators: %s: Item title */+ $output .= '<a aria-label="' . esc_attr( sprintf( __( 'Link to %s', 'gutenverse' ), $item['title'] ) ) . '" href="' . esc_url( $link_url ) . '" class="gallery-link link ' . esc_attr( $zoom_text_class ) . '">';+ if ( $link_text_set ) {+ $output .= '<p class="item-icon-text link-text">' . esc_html( $link_text ) . '</p>';+ }+ if ( $link_icon ) {+ $output .= '<span class="item-icon-inner">';+ if ( 'svg' === $link_icon_type && $link_icon_svg ) {+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode+ $svg_data = base64_decode( $link_icon_svg );+ if ( gutenverse_is_svg_safe( $svg_data ) ) {+ $output .= '<div class="gutenverse-icon-svg">' . $svg_data . '</div>';+ }+ } else {+ $output .= '<i class="' . esc_attr( $link_icon ) . '" aria-hidden="true"></i>';+ }+ $output .= '</span>';+ }+ $output .= '</a>';+ }+ $output .= '</div>'; // item-buttons.+ $output .= '</div>'; // item-caption-over.++ $output .= '<div class="caption-head">';+ if ( ! empty( $item['showPrice'] ) ) {+ $output .= '<div class="item-price">' . esc_html( $item['price'] ) . '</div>';+ }+ if ( ! empty( $item['showRating'] ) ) {+ $output .= '<div class="item-rating">';+ $output .= $this->rating_items( $item['ratingNumber'] );+ $output .= '<span>' . esc_html( $item['ratingNumber'] ) . '</span>';+ $output .= '</div>';+ }+ $output .= '</div>';++ if ( ! empty( $item['showCategory'] ) && ! empty( $item['printLabelCategory'] ) ) {+ $output .= '<div class="caption-category"><span>' . esc_html( $item['category'] ) . '</span></div>';+ }+ } else {+ // Card layout (not overlay).+ $output .= '<div class="caption-head">';+ if ( ! empty( $item['showPrice'] ) ) {+ $output .= '<div class="item-price">' . esc_html( $item['price'] ) . '</div>';+ }+ if ( ! empty( $item['showRating'] ) ) {+ $output .= '<div class="item-rating">';+ $output .= $this->rating_items( $item['ratingNumber'] );+ $output .= '<span>' . esc_html( $item['ratingNumber'] ) . '</span>';+ $output .= '</div>';+ }+ $output .= '</div>';++ $output .= '<div class="caption-button">';+ $output .= '<div class="item-buttons">';+ if ( 'disable' !== $zoom_options && $zoom_icon ) {+ $zoom_text_class = ( 'none' !== $zoom_text ) ? 'with-text' : '';+ $output .= '<div class="gallery-link zoom ' . esc_attr( $zoom_text_class ) . '">';+ if ( $zoom_text_set ) {+ $output .= '<p class="item-icon-text zoom-text">' . esc_html( $zoom_text ) . '</p>';+ }+ $output .= '<span class="item-icon-inner">';+ if ( 'svg' === $zoom_icon_type && $zoom_icon_svg ) {+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode+ $svg_data = base64_decode( $zoom_icon_svg );+ if ( gutenverse_is_svg_safe( $svg_data ) ) {+ $output .= '<div class="gutenverse-icon-svg">' . $svg_data . '</div>';+ }+ } else {+ $output .= '<i class="' . esc_attr( $zoom_icon ) . '" aria-hidden="true"></i>';+ }+ $output .= '</span>';+ $output .= '</div>';+ }++ if ( empty( $item['disableLink'] ) && $link_icon ) {+ $link_url = isset( $item['link'] ) ? $item['link'] : '';+ $zoom_text_class = ( 'none' !== $zoom_text ) ? 'with-text' : '';+ /* translators: %s: Item title */+ $output .= '<a aria-label="' . esc_attr( sprintf( __( 'Link to %s', 'gutenverse' ), $item['title'] ) ) . '" href="' . esc_url( $link_url ) . '" class="gallery-link link ' . esc_attr( $zoom_text_class ) . '">';+ if ( $link_text_set ) {+ $output .= '<p class="item-icon-text link-text">' . esc_html( $link_text ) . '</p>';+ }+ $output .= '<span class="item-icon-inner">';+ if ( 'svg' === $link_icon_type && $link_icon_svg ) {+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode+ $svg_data = base64_decode( $link_icon_svg );+ if ( gutenverse_is_svg_safe( $svg_data ) ) {+ $output .= '<div class="gutenverse-icon-svg">' . $svg_data . '</div>';+ }+ } else {+ $output .= '<i class="' . esc_attr( $link_icon ) . '" aria-hidden="true"></i>';+ }+ $output .= '</span>';+ $output .= '</a>';+ }+ $output .= '</div>'; // item-buttons.+ $output .= '</div>'; // caption-button.++ if ( ! empty( $item['showCategory'] ) ) {+ $output .= '<div class="caption-category"><span>' . esc_html( $item['category'] ) . '</span></div>';+ }+ }+ }++ $output .= '</div>'; // caption-wrap.+ $output .= '</div>'; // thumbnail-wrap.++ if ( 'card' === $layout ) {+ $output .= '<div class="caption-wrap style-card">';+ $output .= '<div class="item-caption-over">';+ $output .= '<' . $title_tag . ' class="item-title">' . wp_kses_post( isset( $item['title'] ) ? $item['title'] : '' ) . '</' . $title_tag . '>';+ $output .= '<div class="item-content"><p>' . wp_kses_post( isset( $item['content'] ) ? $item['content'] : '' ) . '</p></div>';+ $output .= '</div>';+ $output .= '</div>';+ }++ $output .= '</div>'; // grid-item.+ return $output;+ }++ /**+ * Render content logic.+ *+ * @return string+ */+ public function render_content() {+ $element_id = $this->get_element_id();+ $images = isset( $this->attributes['images'] ) ? $this->attributes['images'] : array();+ $showed = isset( $this->attributes['showed'] ) ? $this->attributes['showed'] : 6;+ $filter = isset( $this->attributes['filter'] ) ? $this->attributes['filter'] : false;+ $filter_type = isset( $this->attributes['filterType'] ) ? $this->attributes['filterType'] : 'search';+ $filter_all = isset( $this->attributes['filterAll'] ) ? $this->attributes['filterAll'] : 'All';+ $filter_list = isset( $this->attributes['filterList'] ) ? $this->attributes['filterList'] : array();+ $enable_loadmore = isset( $this->attributes['enableLoadMore'] ) ? $this->attributes['enableLoadMore'] : false;+ $enable_loadtext = isset( $this->attributes['enableLoadText'] ) ? $this->attributes['enableLoadText'] : 'Load More';+ $enable_loadicon = isset( $this->attributes['enableLoadIcon'] ) ? $this->attributes['enableLoadIcon'] : '';+ $enable_loadicon_type = isset( $this->attributes['enableLoadIconType'] ) ? $this->attributes['enableLoadIconType'] : 'icon';+ $enable_loadicon_svg = isset( $this->attributes['enableLoadIconSVG'] ) ? $this->attributes['enableLoadIconSVG'] : '';+ $enable_loadicon_pos = isset( $this->attributes['enableLoadIconPosition'] ) ? $this->attributes['enableLoadIconPosition'] : 'before';+ $filter_search_icon = isset( $this->attributes['filterSearchIcon'] ) ? $this->attributes['filterSearchIcon'] : 'fas fa-angle-down';+ $filter_search_icon_svg = isset( $this->attributes['filterSearchIconSVG'] ) ? $this->attributes['filterSearchIconSVG'] : '';+ $filter_search_icon_type = isset( $this->attributes['filterSearchIconType'] ) ? $this->attributes['filterSearchIconType'] : 'icon';+ $filter_search_icon_pos = isset( $this->attributes['filterSearchIconPosition'] ) ? $this->attributes['filterSearchIconPosition'] : 'after';+ $filter_search_formtext = isset( $this->attributes['filterSearchFormText'] ) ? $this->attributes['filterSearchFormText'] : 'Search Gallery Item...';+ $items_per_load = isset( $this->attributes['itemsPerLoad'] ) ? $this->attributes['itemsPerLoad'] : 2;+ $zoom_options = isset( $this->attributes['zoomOptions'] ) ? $this->attributes['zoomOptions'] : 'item';+ $title_tag = isset( $this->attributes['titleHeadingType'] ) ? $this->attributes['titleHeadingType'] : 'h5';+ $title_tag = $this->check_tag( $title_tag, 'h5' );++ ob_start();+ ?>+ <div class="gutenverse-popup-gallery hidden popup-<?php echo $element_id ?>">+ <div class="gallery-header">+ <div class="left-header"></div>+ <div class="right-header">+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon-fullscreen"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"></path></svg>+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon-minimize hidden"><path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3"></path></svg>+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon-zoom"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="11" y1="8" x2="11" y2="14"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon-close"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>+ </div>+ </div>+ <div class="gallery-body">+ <div class="images">+ <div id="<?php echo esc_attr( $element_id ); ?>" class="swiper-container">+ <div class="swiper-wrapper">+ <?php foreach ( $images as $index => $image ) : ?>+ <div class="swiper-slide image-list image-list-<?php echo esc_attr( $index ); ?>" data-filter="<?php echo esc_attr( isset( $image['id'] ) ? $image['id'] : '' ); ?>" data-title="<?php echo esc_attr( isset( $image['title'] ) ? $image['title'] : '' ); ?>" data-category="<?php echo esc_attr( isset( $image['category'] ) ? $image['category'] : '' ); ?>" data-content="<?php echo esc_attr( isset( $image['content'] ) ? $image['content'] : '' ); ?>" data-index="<?php echo esc_attr( $index ); ?>">+ <div class="content-image swiper-zoom-container">+ <?php echo $this->image_condition( $image ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>+ <?php if ( ! empty( $image['lightboxDescription'] ) ) : ?>+ <div class="content-description-wrapper">+ <<?php echo esc_attr( $title_tag ); ?> class="content-title"><?php echo esc_html( $image['title'] ); ?></<?php echo esc_attr( $title_tag ); ?>>+ <div class="content-description">+ <p><?php echo wp_kses_post( isset( $image['content'] ) ? $image['content'] : '' ); ?></p>+ </div>+ </div>+ <?php endif; ?>+ </div>+ </div>+ <?php endforeach; ?>+ </div>+ <div class="swiper-button-prev"></div>+ <div class="swiper-button-next"></div>+ </div>+ </div>+ </div>+ </div>++ <?php if ( $filter ) : ?>+ <?php if ( 'tab' === $filter_type ) : ?>+ <div class="filter-controls">+ <ul>+ <li class="guten-gallery-control active" data-flag-all="true" data-filter="<?php echo esc_attr( $filter_all ); ?>"><?php echo esc_html( $filter_all ); ?></li>+ <?php foreach ( $filter_list as $filter_item ) : ?>+ <?php if ( ! empty( $filter_item['name'] ) ) : ?>+ <li class="guten-gallery-control" data-filter="<?php echo esc_attr( $filter_item['name'] ); ?>"><?php echo esc_html( $filter_item['name'] ); ?></li>+ <?php endif; ?>+ <?php endforeach; ?>+ </ul>+ </div>+ <?php else : ?>+ <div class="search-filters-wrap">+ <div class="filter-wrap">+ <button id="search-filter-trigger" data-flag-all="true" class="search-filter-trigger icon-position-<?php echo esc_attr( $filter_search_icon_pos ); ?>">+ <?php if ( 'before' === $filter_search_icon_pos ) : ?>+ <?php if ( 'svg' === $filter_search_icon_type && $filter_search_icon_svg ) : ?>+ <?php+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode+ $svg_data = base64_decode( $filter_search_icon_svg );+ if ( gutenverse_is_svg_safe( $svg_data ) ) :+ ?>+ <div class="gutenverse-icon-svg"><?php echo $svg_data; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- sanitized by gutenverse_is_svg_safe ?></div>+ <?php endif; ?>+ <?php else : ?>+ <i aria-hidden="true" class="<?php echo esc_attr( $filter_search_icon ); ?>"></i>+ <?php endif; ?>+ <?php endif; ?>+ <span><?php echo esc_html( $filter_all ); ?></span>+ <?php if ( 'after' === $filter_search_icon_pos ) : ?>+ <?php if ( 'svg' === $filter_search_icon_type && $filter_search_icon_svg ) : ?>+ <?php+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode+ $svg_data = base64_decode( $filter_search_icon_svg );+ if ( gutenverse_is_svg_safe( $svg_data ) ) :+ ?>+ <div class="gutenverse-icon-svg"><?php echo $svg_data; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- sanitized by gutenverse_is_svg_safe ?></div>+ <?php endif; ?>+ <?php else : ?>+ <i aria-hidden="true" class="<?php echo esc_attr( $filter_search_icon ); ?>"></i>+ <?php endif; ?>+ <?php endif; ?>+ </button>+ <ul class="search-filter-controls">+ <li class="guten-gallery-control active" data-flag-all="true" data-filter="<?php echo esc_attr( $filter_all ); ?>"><?php echo esc_html( $filter_all ); ?></li>+ <?php foreach ( $filter_list as $filter_item ) : ?>+ <?php if ( ! empty( $filter_item['name'] ) ) : ?>+ <li class="guten-gallery-control" data-filter="<?php echo esc_attr( $filter_item['name'] ); ?>"><?php echo esc_html( $filter_item['name'] ); ?></li>+ <?php endif; ?>+ <?php endforeach; ?>+ </ul>+ </div>+ <form class="guten-gallery-search-box" id="guten-gallery-search-box" autocomplete="off">+ <input type="text" id="guten-gallery-search-box-input" name="guten-frontend-search" placeholder="<?php echo esc_attr( $filter_search_formtext ); ?>" />+ </form>+ </div>+ <?php endif; ?>+ <?php endif; ?>++ <div class="gallery-items" data-loaded="<?php echo esc_attr( $showed ); ?>" data-more="<?php echo esc_attr( $items_per_load ); ?>" data-max="<?php echo esc_attr( count( $images ) ); ?>" <?php echo ( $zoom_options && 'item' !== $zoom_options ) ? 'data-zoom="' . esc_attr( $zoom_options ) . '"' : ''; ?>>+ <?php foreach ( $images as $index => $item ) : ?>+ <div class="gallery-item-wrap <?php echo esc_attr( $index >= $showed ? 'item-hidden' : '' ); ?>" data-index="<?php echo esc_attr( $index ); ?>" data-control="<?php echo esc_attr( isset( $item['id'] ) ? $item['id'] : '' ); ?>">+ <?php echo $this->render_gallery_item( $item ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>+ </div>+ <?php endforeach; ?>+ </div>++ <?php if ( $enable_loadmore && ( $showed < count( $images ) ) ) : ?>+ <div class="load-more-items">+ <div class="guten-gallery-loadmore">+ <a aria-label="Load more" href="#" class="guten-gallery-load-more">+ <?php if ( $enable_loadicon && 'before' === $enable_loadicon_pos ) : ?>+ <span class="load-more-icon icon-position-before" aria-hidden="true">+ <?php if ( 'svg' === $enable_loadicon_type && $enable_loadicon_svg ) : ?>+ <?php+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode+ $svg_data = base64_decode( $enable_loadicon_svg );+ if ( gutenverse_is_svg_safe( $svg_data ) ) :+ ?>+ <div class="gutenverse-icon-svg"><?php echo $svg_data; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- sanitized by gutenverse_is_svg_safe ?></div>+ <?php endif; ?>+ <?php else : ?>+ <i class="<?php echo esc_attr( $enable_loadicon ); ?>"></i>+ <?php endif; ?>+ </span>+ <?php endif; ?>+ <span class="load-more-text"><?php echo esc_html( $enable_loadtext ); ?></span>+ <?php if ( $enable_loadicon && 'after' === $enable_loadicon_pos ) : ?>+ <span class="load-more-icon icon-position-after" aria-hidden="true">+ <?php if ( 'svg' === $enable_loadicon_type && $enable_loadicon_svg ) : ?>+ <?php+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode+ $svg_data = base64_decode( $enable_loadicon_svg );+ if ( gutenverse_is_svg_safe( $svg_data ) ) :+ ?>+ <div class="gutenverse-icon-svg"><?php echo $svg_data; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- sanitized by gutenverse_is_svg_safe ?></div>+ <?php endif; ?>+ <?php else : ?>+ <i class="<?php echo esc_attr( $enable_loadicon ); ?>"></i>+ <?php endif; ?>+ </span>+ <?php endif; ?>+ </a>+ </div>+ </div>+ <?php endif; ?>+ <?php+ return ob_get_clean();+ }++ /**+ * Render view in editor.+ */+ public function render_gutenberg() {+ return $this->render_content();+ }++ /**+ * Render view in frontend.+ */+ public function render_frontend() {+ if ( ! empty( trim( $this->block_data->inner_html ) ) && apply_filters( 'gutenverse_force_dynamic', false ) ) {+ return $this->content;+ }+ $element_id = $this->get_element_id();+ $grid = isset( $this->attributes['grid'] ) ? $this->attributes['grid'] : 'grid';+ $column = isset( $this->attributes['column'] ) ? $this->attributes['column'] : array();+ $layout = isset( $this->attributes['layout'] ) ? $this->attributes['layout'] : 'overlay';+ $display_classes = $this->set_display_classes();+ $animation_class = $this->set_animation_classes();+ $custom_classes = $this->get_custom_classes();+ $filter_remove_animation = isset( $this->attributes['filterRemoveAnimation'] ) ? $this->attributes['filterRemoveAnimation'] : false;++ $col_desktop = isset( $column['Desktop'] ) ? $column['Desktop'] : 3;+ $col_tablet = isset( $column['Tablet'] ) ? $column['Tablet'] : 2;+ $col_mobile = isset( $column['Mobile'] ) ? $column['Mobile'] : 2;++ $anchor = isset( $this->attributes['anchor'] ) ? $this->attributes['anchor'] : '';+ $class_name = trim( "guten-element guten-gallery $element_id $animation_class $display_classes layout-$layout grid-desktop-$col_desktop grid-tablet-$col_tablet grid-mobile-$col_mobile $custom_classes" );+ $data_id = '';+ if ( isset( $this->attributes['advanceAnimation']['type'] ) && ! empty( $this->attributes['advanceAnimation']['type'] ) ) {+ $id_parts = explode( '-', $element_id );+ if ( count( $id_parts ) > 1 ) {+ $data_id = ' data-id="' . esc_attr( $id_parts[1] ) . '"';+ }+ }++ $id_attr = ! empty( $anchor ) ? ' id="' . esc_attr( $anchor ) . '"' : '';+ $output = '<div' . $id_attr . ' class="' . esc_attr( $class_name ) . '" data-grid="' . esc_attr( $grid ) . '"' . ( $filter_remove_animation ? ' data-remove-animation="true"' : '' ) . $data_id . '>';+ $output .= $this->render_content(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped+ $output .= '</div>';++ $output = apply_filters( 'gutenverse_cursor_move_effect_script', $output, $this->attributes, $element_id );+ $output = apply_filters( 'gutenverse_advance_animation_script', $output, $this->attributes, $element_id, 'gallery' );++ return $output;+ }+}
AI Analysis
Vulnerability Existed: yes
**Improper Neutralization of Input During Web Page Generation (Cross-site Scripting - XSS)** [class-gallery.php] [Lines 313, 323, 371, 381, 414, 424]
Old Code:
```php
<div class="gutenverse-popup-gallery hidden popup-<?php echo $element_id ?>">
```
and similar instances where `$element_id` is echoed without escaping, such as:
```php
<div id="<?php echo esc_attr( $element_id ); ?>" class="swiper-container">
```
Fixed Code:
```php
<div class="gutenverse-popup-gallery hidden popup-<?php echo esc_attr( $element_id ); ?>">
```
**Explanation:** The variable `$element_id` is output directly in line 313 without using `esc_attr()`. While it is properly escaped in some places (line 318), it is not consistently escaped throughout the file. This inconsistency could allow XSS attacks if `$element_id` contains malicious data. All attribute values should be escaped using `esc_attr()`.
---
Vulnerability Existed: not sure
**Potential Code Injection via base64_decode** [class-gallery.php] [Lines 160, 173, 192, 205, 282, 292, 369, 379, 412, 422]
Old Code:
```php
$svg_data = base64_decode( $zoom_icon_svg );
if ( gutenverse_is_svg_safe( $svg_data ) ) {
$output .= '<div class="gutenverse-icon-svg">' . $svg_data . '</div>';
}
```
Fixed Code:
The code appears to have attempted mitigation through the `gutenverse_is_svg_safe()` function. However, without seeing the implementation of this function, it's unclear if it provides adequate protection against SVG-based XSS attacks (e.g., embedded JavaScript in SVG elements).
**Explanation:** Multiple instances of `base64_decode()` are used on user-supplied data with a check via `gutenverse_is_svg_safe()`. While there are phpcs ignore comments, the actual security depends on the robustness of the validation function, which is not visible in this file.
CVE Analysis Results:
CVE-2026-2868: Yes
View CVE Description
The Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'separatorIconSVG' parameter in versions up to, and including, 3.5.3 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
includes/block/class-icon-list-item.php
AI: 2 vulnerabilities
CVE-2026-2868
--- /dev/null+++ cache/gutenverse_3.6.0/includes/block/class-icon-list-item.php@@ -0,0 +1,105 @@+<?php+/**+ * Icon List Item Block class+ *+ * @author Jegstudio+ * @since 1.0.0+ * @package gutenverse\block+ */++namespace Gutenverse\Block;++use Gutenverse\Framework\Block\Block_Abstract;++/**+ * Class Icon List Item Block+ *+ * @package gutenverse\block+ */+class Icon_List_Item extends Block_Abstract {++ /**+ * Render content+ *+ * @return string+ */+ public function render_content() {+ $element_id = $this->get_element_id();+ $url = isset( $this->attributes['url'] ) ? $this->attributes['url'] : '';+ $link_target = isset( $this->attributes['linkTarget'] ) ? $this->attributes['linkTarget'] : '';+ $rel = isset( $this->attributes['rel'] ) ? $this->attributes['rel'] : '';+ $aria_label = isset( $this->attributes['ariaLabel'] ) ? $this->attributes['ariaLabel'] : '';+ $icon = isset( $this->attributes['icon'] ) ? $this->attributes['icon'] : '';+ $icon_type = isset( $this->attributes['iconType'] ) ? $this->attributes['iconType'] : 'icon';+ $icon_svg = isset( $this->attributes['iconSVG'] ) ? $this->attributes['iconSVG'] : '';+ $hide_icon = isset( $this->attributes['hideIcon'] ) ? $this->attributes['hideIcon'] : false;+ $text = isset( $this->attributes['text'] ) ? $this->attributes['text'] : '';++ $text = apply_filters(+ 'gutenverse_dynamic_generate_dynamic_parse_list_php',+ $text,+ $this->attributes['dynamicDataList'] ?? array()+ );++ $dynamic_url = isset( $this->attributes['dynamicUrl'] ) ? $this->attributes['dynamicUrl'] : array();+ $href = apply_filters(+ 'gutenverse_dynamic_generate_url',+ $url,+ $dynamic_url,+ $this->get_element_id()+ );++ $icon_html = '';+ if ( ! $hide_icon ) {+ if ( 'svg' === $icon_type && $icon_svg ) {+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode+ $svg_data = base64_decode( $icon_svg );+ if ( gutenverse_is_svg_safe( $svg_data ) ) {+ $icon_html = '<div class="gutenverse-icon-svg">' . $svg_data . '</div>';+ }+ } elseif ( $icon ) {+ $icon_html = '<i class="' . esc_attr( $icon ) . '"></i>';+ }+ }++ $text_class = 'list-text' . ( $hide_icon ? ' no-icon' : '' );++ $target_attr = ! empty( $link_target ) ? ' target="' . esc_attr( $link_target ) . '"' : '';+ $rel_attr = ! empty( $rel ) ? ' rel="' . esc_attr( $rel ) . '"' : '';+ $aria_label_attr = ! empty( $aria_label ) ? ' aria-label="' . esc_attr( $aria_label ) . '"' : '';++ $content = '<div class="list-divider"></div>';+ $content .= '<a id="' . esc_attr( $element_id ) . '" href="' . esc_url( $href ) . '"' . $target_attr . $rel_attr . $aria_label_attr . '>';+ $content .= $icon_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped+ $content .= '<span class="' . esc_attr( $text_class ) . '">' . $text . '</span>';+ $content .= '</a>';++ return $content;+ }++ /**+ * Render view in editor+ */+ public function render_gutenberg() {+ return $this->render_content();+ }++ /**+ * Render view in frontend+ */+ public function render_frontend() {+ if ( ! empty( trim( $this->block_data->inner_html ) ) && apply_filters( 'gutenverse_force_dynamic', false ) ) {+ return $this->content;+ }+ $element_id = $this->get_element_id();+ $anchor = isset( $this->attributes['anchor'] ) ? $this->attributes['anchor'] : '';+ $display_classes = $this->set_display_classes();+ $animation_class = $this->set_animation_classes();+ $custom_classes = $this->get_custom_classes();++ $id_attr = ! empty( $anchor ) ? ' id="' . esc_attr( $anchor ) . '"' : '';+ $class_name = trim( 'guten-element guten-icon-list-item ' . $element_id . ' ' . $animation_class . ' ' . $display_classes . ' ' . $custom_classes );++ return '<div' . $id_attr . ' class="' . esc_attr( $class_name ) . '">' . $this->render_content() . '</div>';+ }+}
AI Analysis
# Security Analysis Results
Vulnerability Existed: yes
**Cross-Site Scripting (XSS) via Unescaped SVG Data** [includes/block/class-icon-list-item.php] [Lines 54-58]
**Old Code:**
```php
if ( 'svg' === $icon_type && $icon_svg ) {
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
$svg_data = base64_decode( $icon_svg );
if ( gutenverse_is_svg_safe( $svg_data ) ) {
$icon_html = '<div class="gutenverse-icon-svg">' . $svg_data . '</div>';
}
}
```
**Fixed Code:**
```php
if ( 'svg' === $icon_type && $icon_svg ) {
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
$svg_data = base64_decode( $icon_svg );
if ( gutenverse_is_svg_safe( $svg_data ) ) {
$icon_html = '<div class="gutenverse-icon-svg">' . wp_kses_post( $svg_data ) . '</div>';
}
}
```
**Explanation:** The `$svg_data` variable is output directly into HTML without proper escaping. While `gutenverse_is_svg_safe()` provides some validation, SVG content should still be escaped using `wp_kses_post()` to prevent potential XSS attacks. The code already has a phpcs ignore comment on line 73 acknowledging unsafe output of `$icon_html`, but the SVG data itself should be properly sanitized before insertion.
---
Vulnerability Existed: yes
**Cross-Site Scripting (XSS) via Unescaped Text Content** [includes/block/class-icon-list-item.php] [Lines 74]
**Old Code:**
```php
$content .= '<span class="' . esc_attr( $text_class ) . '">' . $text . '</span>';
```
**Fixed Code:**
```php
$content .= '<span class="' . esc_attr( $text_class ) . '">' . wp_kses_post( $text ) . '</span>';
```
**Explanation:** The `$text` variable is output without escaping. Although it's processed through a filter, the output should be escaped using `wp_kses_post()` to prevent XSS attacks and ensure safe HTML rendering.
CVE Analysis Results:
CVE-2026-2868: Yes
View CVE Description
The Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'separatorIconSVG' parameter in versions up to, and including, 3.5.3 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
includes/block/class-icon.php
AI: 2 vulnerabilities
CVE-2026-2868
--- /dev/null+++ cache/gutenverse_3.6.0/includes/block/class-icon.php@@ -0,0 +1,132 @@+<?php+/**+ * Icon Block class+ *+ * @author Jegstudio+ * @since 1.0.0+ * @package gutenverse\block+ */++namespace Gutenverse\Block;++use Gutenverse\Framework\Block\Block_Abstract;++/**+ * Class Icon Block+ *+ * @package gutenverse\block+ */+class Icon extends Block_Abstract {+ /**+ * Render content+ *+ * @return string+ */+ public function render_content() {+ $icon = isset( $this->attributes['icon'] ) ? $this->attributes['icon'] : 'fab fa-wordpress';+ $icon_type = isset( $this->attributes['iconType'] ) ? $this->attributes['iconType'] : 'icon';+ $icon_svg = isset( $this->attributes['iconSVG'] ) ? $this->attributes['iconSVG'] : '';+ $url = isset( $this->attributes['url'] ) ? $this->attributes['url'] : '';+ $aria_label = isset( $this->attributes['ariaLabel'] ) ? $this->attributes['ariaLabel'] : '';+ $link_target = isset( $this->attributes['linkTarget'] ) ? $this->attributes['linkTarget'] : '';+ $rel = isset( $this->attributes['rel'] ) ? $this->attributes['rel'] : '';+ $icon_shape = isset( $this->attributes['iconShape'] ) ? $this->attributes['iconShape'] : 'rounded';+ $icon_view = isset( $this->attributes['iconView'] ) ? $this->attributes['iconView'] : 'stacked';++ // Dynamic icon.+ $dynamic_icon = isset( $this->attributes['dynamicIcon'] ) ? $this->attributes['dynamicIcon'] : array();+ $default_icon = array(+ 'type' => $icon_type,+ 'icon' => $icon,+ 'svg' => $icon_svg,+ );+ $resolved = apply_filters( 'gutenverse_dynamic_generate_icon', $default_icon, $dynamic_icon );++ if ( ! empty( $resolved ) && is_array( $resolved ) ) {+ $icon_type = isset( $resolved['type'] ) ? $resolved['type'] : $icon_type;+ if ( 'icon' === $icon_type ) {+ $icon = isset( $resolved['icon'] ) ? $resolved['icon'] : $icon;+ } else {+ $icon_svg = isset( $resolved['svg'] ) ? $resolved['svg'] : $icon_svg;+ }+ }++ if ( 'svg' === $icon_type ) {+ $icon_html = $this->render_icon( $icon_type, $icon, $icon_svg );+ } else {+ $icon_html = '<i class="' . esc_attr( $icon ) . '"></i>';+ }++ // Dynamic URL.+ $element_id = $this->get_element_id();+ $dynamic_url = isset( $this->attributes['dynamicUrl'] ) ? $this->attributes['dynamicUrl'] : array();+ $href = apply_filters( 'gutenverse_dynamic_generate_url', $url, $dynamic_url, $element_id );++ $wrapper_class = 'guten-icon-wrapper';+ if ( ! empty( $icon_shape ) ) {+ $wrapper_class .= ' ' . $icon_shape;+ }+ if ( ! empty( $icon_view ) ) {+ $wrapper_class .= ' ' . $icon_view;+ }++ if ( ! empty( $url ) ) {+ $link_attr = array(+ 'class' => $wrapper_class,+ 'href' => $href,+ 'target' => $link_target,+ 'rel' => $rel,+ 'aria-label' => $aria_label,+ );+ $link_attr_str = '';+ foreach ( $link_attr as $key => $val ) {+ if ( ! empty( $val ) ) {+ $link_attr_str .= ' ' . esc_attr( $key ) . '="' . esc_attr( $val ) . '"';+ }+ }+ $icon_wrapper = '<a' . $link_attr_str . '>' . $icon_html . '</a>';+ } else {+ $icon_wrapper = '<span class="' . esc_attr( $wrapper_class ) . '">' . $icon_html . '</span>';+ }++ return $icon_wrapper;+ }++ /**+ * Render view in editor+ */+ public function render_gutenberg() {+ return null;+ }++ /**+ * Render view in frontend+ */+ public function render_frontend() {+ if ( ! empty( trim( $this->block_data->inner_html ) ) && apply_filters( 'gutenverse_force_dynamic', false ) ) {+ return $this->content;+ }+ $post_id = ! empty( $this->context['postId'] ) ? esc_html( $this->context['postId'] ) : get_the_ID();+ $element_id = $this->get_element_id();+ $anchor = isset( $this->attributes['anchor'] ) ? $this->attributes['anchor'] : '';+ $display_classes = $this->set_display_classes();+ $animation_class = $this->set_animation_classes();+ $custom_classes = $this->get_custom_classes();++ $data_id = '';+ if ( isset( $this->attributes['advanceAnimation']['type'] ) && ! empty( $this->attributes['advanceAnimation']['type'] ) ) {+ $id_parts = explode( '-', $element_id );+ if ( count( $id_parts ) > 1 ) {+ $data_id = ' data-id="' . esc_attr( $id_parts[1] ) . '"';+ }+ }++ $id_attr = ! empty( $anchor ) ? ' id="' . esc_attr( $anchor ) . '"' : '';+ $class_name = trim( 'guten-element wp-block-gutenverse-icon ' . $element_id . ' guten-icon' . $animation_class . $display_classes . $custom_classes );+ $content = '<div' . $id_attr . ' class="' . esc_attr( $class_name ) . '"' . $data_id . '>' . $this->render_content() . '</div>';+ $content = apply_filters( 'gutenverse_cursor_move_effect_script', $content, $this->attributes, $element_id );+ $content = apply_filters( 'gutenverse_advance_animation_script', $content, $this->attributes, $element_id, 'icon' );++ return $content;+ }+}
AI Analysis
# Security Analysis: Icon Block Class
Vulnerability Existed: yes
**Cross-Site Scripting (XSS) via Unescaped SVG Content** [includes/block/class-icon.php] [Lines 54-56]
**Old Code:**
```php
if ( 'svg' === $icon_type ) {
$icon_html = $this->render_icon( $icon_type, $icon, $icon_svg );
} else {
$icon_html = '<i class="' . esc_attr( $icon ) . '"></i>';
}
```
**Issue:**
The `$icon_svg` variable is passed to `render_icon()` method without sanitization. If `render_icon()` outputs the SVG directly without proper escaping, this creates an XSS vulnerability. SVG content from `$this->attributes['iconSVG']` (line 27) is user-controlled and can contain malicious JavaScript.
**Fixed Code:**
```php
if ( 'svg' === $icon_type ) {
$icon_html = $this->render_icon( $icon_type, $icon, wp_kses_post( $icon_svg ) );
} else {
$icon_html = '<i class="' . esc_attr( $icon ) . '"></i>';
}
```
---
Vulnerability Existed: yes
**Potential DOM-based XSS via Dynamic URL Filter** [includes/block/class-icon.php] [Lines 61-62]
**Old Code:**
```php
$dynamic_url = isset( $this->attributes['dynamicUrl'] ) ? $this->attributes['dynamicUrl'] : array();
$href = apply_filters( 'gutenverse_dynamic_generate_url', $url, $dynamic_url, $element_id );
```
**Issue:**
The `$href` returned from the filter is used in line 75 without escaping. If the filter returns unescaped content or if `$url` contains malicious input, this can lead to XSS via href attributes (e.g., `javascript:alert()`).
**Fixed Code:**
```php
$dynamic_url = isset( $this->attributes['dynamicUrl'] ) ? $this->attributes['dynamicUrl'] : array();
$href = apply_filters( 'gutenverse_dynamic_generate_url', $url, $dynamic_url, $element_id );
$href = esc_url( $href );
```
CVE Analysis Results:
CVE-2026-2868: Yes
View CVE Description
The Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'separatorIconSVG' parameter in versions up to, and including, 3.5.3 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
includes/block/class-image-box.php
AI: No vulnerabilities
CVE-2026-2868
--- /dev/null+++ cache/gutenverse_3.6.0/includes/block/class-image-box.php@@ -0,0 +1,221 @@+<?php+/**+ * Image Box Block class+ *+ * @author Jegstudio+ * @since 1.0.0+ * @package gutenverse\block+ */++namespace Gutenverse\Block;++use Gutenverse\Framework\Block\Block_Abstract;++/**+ * Class Image Box Block+ *+ * @package gutenverse\block+ */+class Image_Box extends Block_Abstract {++ /**+ * Render the image figure HTML.+ *+ * @return string+ */+ private function render_figure() {+ $image = isset( $this->attributes['image'] ) ? $this->attributes['image'] : array();+ $image_alt = isset( $this->attributes['imageAlt'] ) ? $this->attributes['imageAlt'] : '';+ $alt_type = isset( $this->attributes['altType'] ) ? $this->attributes['altType'] : 'custom';+ $alt_orig = isset( $this->attributes['altOriginal'] ) ? $this->attributes['altOriginal'] : '';+ $image_load = isset( $this->attributes['imageLoad'] ) ? $this->attributes['imageLoad'] : '';+ $lazy_attr = ( 'lazy' === $image_load ) ? ' loading="lazy"' : '';++ $alt_text = $image_alt;+ if ( 'original' === $alt_type ) {+ $alt_text = $alt_orig;+ }++ $media = isset( $image['media'] ) ? $image['media'] : array();+ $size = isset( $image['size'] ) ? $image['size'] : 'full';+ $image_id = isset( $media['imageId'] ) ? $media['imageId'] : 0;+ $sizes = isset( $media['sizes'] ) ? $media['sizes'] : array();++ if ( empty( $sizes ) ) {+ return '<img class="gutenverse-image-box-empty" src=""' . $lazy_attr . ' alt="' . esc_attr( $alt_text ) . '" />';+ }++ $image_src = isset( $sizes[ $size ] ) ? $sizes[ $size ] : array();+ if ( empty( $image_src ) ) {+ $image_src = isset( $sizes['full'] ) ? $sizes['full'] : array();+ }++ if ( $image_id && ! empty( $image_src ) ) {+ $url = isset( $image_src['url'] ) ? $image_src['url'] : '';+ $height = isset( $image_src['height'] ) ? $image_src['height'] : '';+ $width = isset( $image_src['width'] ) ? $image_src['width'] : '';+ $height_attr = ! empty( $height ) ? ' height="' . esc_attr( $height ) . '"' : '';+ $width_attr = ! empty( $width ) ? ' width="' . esc_attr( $width ) . '"' : '';+ return '<img class="gutenverse-image-box-filled" src="' . esc_url( $url ) . '"' . $height_attr . $width_attr . ' alt="' . esc_attr( $alt_text ) . '"' . $lazy_attr . ' />';+ }++ return '<img class="gutenverse-image-box-empty" src=""' . $lazy_attr . ' alt="' . esc_attr( $alt_text ) . '" />';+ }++ /**+ * Wrap element in an anchor tag if URL is set.+ *+ * @param string $content .+ * @param string $css_class CSS class for the anchor tag.+ * @return string+ */+ private function wrap_href( $content, $css_class = '' ) {+ $url = ! empty( $this->attributes['url'] ) ? $this->attributes['url'] : '';+ $link_target = ! empty( $this->attributes['linkTarget'] ) ? $this->attributes['linkTarget'] : '';+ $rel = ! empty( $this->attributes['rel'] ) ? $this->attributes['rel'] : '';+ $aria_label = ! empty( $this->attributes['ariaLabel'] ) ? $this->attributes['ariaLabel'] : '';++ if ( ! empty( $url ) ) {+ $dynamic_url = isset( $this->attributes['dynamicUrl'] ) ? $this->attributes['dynamicUrl'] : array();+ $href = apply_filters(+ 'gutenverse_dynamic_generate_url',+ $url,+ $dynamic_url,+ $this->get_element_id()+ );++ $aria_attr = ! empty( $aria_label ) ? ' aria-label="' . esc_attr( $aria_label ) . '"' : '';++ return '<a class="' . esc_attr( $css_class ) . '" href="' . esc_url( (string) $href ) . '" target="' . esc_attr( $link_target ) . '"' . $aria_attr . ' rel="' . esc_attr( $rel ) . '">' . $content . '</a>';+ }++ return $content;+ }++ /**+ * Render icon HTML+ *+ * @param string $position Check if icon matches position.+ * @return string+ */+ private function render_title_icon( $position ) {+ $title_icon = isset( $this->attributes['titleIcon'] ) ? $this->attributes['titleIcon'] : '';+ $title_icon_type = isset( $this->attributes['titleIconType'] ) ? $this->attributes['titleIconType'] : 'icon';+ $title_icon_svg = isset( $this->attributes['titleIconSVG'] ) ? $this->attributes['titleIconSVG'] : '';+ $title_icon_position = isset( $this->attributes['titleIconPosition'] ) ? $this->attributes['titleIconPosition'] : 'before';++ if ( $title_icon_position !== $position || empty( $title_icon ) ) {+ return '';+ }++ $pos_class = 'icon-position-' . $position;++ if ( 'svg' === $title_icon_type && ! empty( $title_icon_svg ) ) {+ return '<span class="image-box-icon ' . esc_attr( $pos_class ) . '">' . $title_icon_svg . '</span>';+ }++ return '<span class="image-box-icon ' . esc_attr( $pos_class ) . '"><i class="' . esc_attr( $title_icon ) . '"></i></span>';+ }++ /**+ * Render content+ *+ * @return string+ */+ public function render_content() {+ $title = isset( $this->attributes['title'] ) ? $this->attributes['title'] : '';+ $description = isset( $this->attributes['description'] ) ? $this->attributes['description'] : '';+ $title_tag = isset( $this->attributes['titleTag'] ) ? $this->attributes['titleTag'] : 'h3';+ $title_icon_position = isset( $this->attributes['titleIconPosition'] ) ? $this->attributes['titleIconPosition'] : 'before';+ $hover_bottom = isset( $this->attributes['hoverBottom'] ) && $this->attributes['hoverBottom'];+ $hover_direction = isset( $this->attributes['hoverBottomDirection'] ) ? $this->attributes['hoverBottomDirection'] : 'left';+ $include_button = isset( $this->attributes['includeButton'] ) && $this->attributes['includeButton'];++ $figure_html = $this->render_figure();++ $output = '<div class="inner-container">';+ $output .= '<div class="image-box-header">';+ $output .= $this->wrap_href( $figure_html );+ $output .= '</div>';++ $output .= '<div class="image-box-body">';+ $output .= '<div class="body-inner">';++ if ( ! empty( $title ) ) {+ $title = apply_filters(+ 'gutenverse_dynamic_generate_dynamic_parse_list_php',+ $title,+ $this->attributes['titleDynamicList'] ?? array()+ );++ $title_class = 'body-title icon-position-' . esc_attr( $title_icon_position );+ $title_inner = $this->render_title_icon( 'before' );+ $title_inner .= '<span>' . wp_kses_post( $title ) . '</span>';+ $title_inner .= $this->render_title_icon( 'after' );+ $title_html = '<' . esc_attr( $title_tag ) . ' class="' . esc_attr( $title_class ) . '">' . $title_inner . '</' . esc_attr( $title_tag ) . '>';+ $output .= $this->wrap_href( $title_html );+ }++ if ( ! empty( $description ) ) {+ $description = apply_filters(+ 'gutenverse_dynamic_generate_dynamic_parse_list_php',+ $description,+ $this->attributes['descriptionDynamicList'] ?? array()+ );++ $desc_html = '<p class="body-description">' . wp_kses_post( $description ) . '</p>';+ $output .= $this->wrap_href( $desc_html );+ }++ if ( $include_button ) {+ $output .= $this->get_inner_blocks_content();+ }++ if ( $hover_bottom ) {+ $output .= '<div class="border-bottom"><div class="animated ' . esc_attr( $hover_direction ) . '"></div></div>';+ }++ $output .= '</div>';+ $output .= '</div>';+ $output .= '</div>';++ return $output;+ }++ /**+ * Render view in editor+ */+ public function render_gutenberg() {+ return $this->render_content();+ }++ /**+ * Render view in frontend+ */+ public function render_frontend() {+ $element_id = $this->get_element_id();+ $anchor = isset( $this->attributes['anchor'] ) ? $this->attributes['anchor'] : '';+ $display_classes = $this->set_display_classes();+ $animation_class = $this->set_animation_classes();+ $custom_classes = $this->get_custom_classes();+ $content_style = isset( $this->attributes['contentStyle'] ) ? $this->attributes['contentStyle'] : 'default';++ $id_attr = ! empty( $anchor ) ? ' id="' . esc_attr( $anchor ) . '"' : '';++ $data_id = '';+ if ( isset( $this->attributes['advanceAnimation']['type'] ) && ! empty( $this->attributes['advanceAnimation']['type'] ) ) {+ $id_parts = explode( '-', $element_id );+ if ( count( $id_parts ) > 1 ) {+ $data_id = ' data-id="' . esc_attr( $id_parts[1] ) . '"';+ }+ }++ $class_name = $element_id . ' guten-image-box guten-element style-' . $content_style . $display_classes . $animation_class . $custom_classes;++ $content = '<div' . $id_attr . ' class="' . esc_attr( trim( $class_name ) ) . '"' . $data_id . '>' . $this->render_content() . '</div>';+ $content = apply_filters( 'gutenverse_cursor_move_effect_script', $content, $this->attributes, $element_id );+ $content = apply_filters( 'gutenverse_advance_animation_script', $content, $this->attributes, $element_id, 'image-box' );++ return $content;+ }+}
AI Analysis
# Security Analysis Report ## Summary This is a new file containing a WordPress block class for an image box component. The code implements proper security practices for a block rendering class. --- ## Vulnerabilities Found **Vulnerability Existed: No** --- ## Security Assessment Details ### Positive Security Findings: 1. **Output Escaping** (Lines 44, 57, 58, 61, 83, 87, 114, 115, 156, 166, 201, 206, 210, 212, 213): - Proper use of `esc_attr()` for HTML attributes - Proper use of `esc_url()` for URL outputs - Proper use of `wp_kses_post()` for user content containing HTML 2. **Input Validation**: - Attributes are safely retrieved using `isset()` with default fallback values - Image IDs and URLs are validated before use 3. **SVG Handling** (Line 113): - SVG content is directly output without escaping, but this appears intentional for SVG rendering. However, there is a potential risk here if `$title_icon_svg` comes from user input without prior sanitization. 4. **Dynamic Content Filtering** (Lines 136-140, 160-164): - Proper use of `apply_filters()` for dynamic content generation --- ## Minor Observation (Not a Vulnerability) **Potential Security Concern: SVG Output Without Escaping** - **File**: includes/block/class-image-box.php - **Line**: 113 - **Issue**: The SVG content (`$title_icon_svg`) is output directly without sanitization. If this value originates from user input, it could potentially allow XSS attacks. However, this depends on where `titleIconSVG` is sanitized upstream. - **Recommendation**: Ensure `titleIconSVG` is properly sanitized before being stored in attributes (likely in a save callback or server-side registration). --- **Overall Assessment**: The code follows WordPress security best practices with proper escaping functions for output. No active vulnerabilities were identified in this file.
CVE Analysis Results:
CVE-2026-2868: Yes
View CVE Description
The Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'separatorIconSVG' parameter in versions up to, and including, 3.5.3 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
includes/block/class-search.php
AI: 1 vulnerabilities
CVE-2026-2868
--- /dev/null+++ cache/gutenverse_3.6.0/includes/block/class-search.php@@ -0,0 +1,98 @@+<?php+/**+ * Search Block class+ *+ * @author Jegstudio+ * @since 1.0.0+ * @package gutenverse\block+ */++namespace Gutenverse\Block;++use Gutenverse\Framework\Block\Block_Abstract;++/**+ * Class Search Block+ *+ * @package gutenverse\block+ */+class Search extends Block_Abstract {++ /**+ * Render the close icon.+ *+ * @return string+ */+ private function render_close_icon() {+ $close_icon = isset( $this->attributes['closeIcon'] ) ? $this->attributes['closeIcon'] : 'gtn gtn-x-line';+ $close_icon_type = isset( $this->attributes['closeIconType'] ) ? $this->attributes['closeIconType'] : 'icon';+ $close_icon_svg = isset( $this->attributes['closeIconSVG'] ) ? $this->attributes['closeIconSVG'] : '';++ return '<div class="close-icon">' . $this->render_icon( $close_icon_type, $close_icon, $close_icon_svg ) . '</div>';+ }++ /**+ * Render content+ *+ * @return string+ */+ public function render_content() {+ $placeholder = isset( $this->attributes['inputPlaceholder'] ) ? $this->attributes['inputPlaceholder'] : 'Text Placeholder';+ $show_button = isset( $this->attributes['showButton'] ) ? $this->attributes['showButton'] : true;++ $output = '<form class="gutenverse-search-form">';+ $output .= '<div class="search-input-container-outer">';+ $output .= '<div class="search-input-container">';+ $output .= '<input type="text" placeholder="' . esc_attr( $placeholder ) . '" name="s" class="gutenverse-search gutenverse-search-input" />';+ $output .= $this->render_close_icon();+ $output .= '</div>';+ $output .= '</div>';++ if ( $show_button ) {+ $output .= '<div class="guten-search-button-wrapper">' . $this->get_inner_blocks_content() . '</div>';+ }++ $output .= '</form>';++ return $output;+ }++ /**+ * Render view in editor+ */+ public function render_gutenberg() {+ return null;+ }++ /**+ * Render view in frontend+ */+ public function render_frontend() {+ if ( ! empty( trim( $this->block_data->inner_html ) ) && apply_filters( 'gutenverse_force_dynamic', false ) ) {+ return $this->content;+ }++ $element_id = $this->get_element_id();+ $anchor = isset( $this->attributes['anchor'] ) ? $this->attributes['anchor'] : '';+ $display_classes = $this->set_display_classes();+ $animation_class = $this->set_animation_classes();+ $custom_classes = $this->get_custom_classes();++ $id_attr = ! empty( $anchor ) ? ' id="' . esc_attr( $anchor ) . '"' : '';++ $data_id = '';+ if ( isset( $this->attributes['advanceAnimation']['type'] ) && ! empty( $this->attributes['advanceAnimation']['type'] ) ) {+ $id_parts = explode( '-', $element_id );+ if ( count( $id_parts ) > 1 ) {+ $data_id = ' data-id="' . esc_attr( $id_parts[1] ) . '"';+ }+ }++ $class_name = trim( 'guten-element ' . $element_id . ' guten-search' . $animation_class . $display_classes . $custom_classes );+ $content = '<div' . $id_attr . ' class="' . esc_attr( $class_name ) . '"' . $data_id . '>' . $this->render_content() . '</div>';+ $content = apply_filters( 'gutenverse_cursor_move_effect_script', $content, $this->attributes, $element_id );+ $content = apply_filters( 'gutenverse_advance_animation_script', $content, $this->attributes, $element_id, 'search' );++ return $content;+ }+}
AI Analysis
Vulnerability Existed: yes **Cross-Site Scripting (XSS) - Unescaped Output** [includes/block/class-search.php] [Lines 31, 89-90, 92] **Old Code:** ```php // Line 31 return '<div class="close-icon">' . $this->render_icon( $close_icon_type, $close_icon, $close_icon_svg ) . '</div>'; // Lines 89-90 $id_attr = ! empty( $anchor ) ? ' id="' . esc_attr( $anchor ) . '"' : ''; $data_id = ' data-id="' . esc_attr( $id_parts[1] ) . '"'; // Line 92 $content = '<div' . $id_attr . ' class="' . esc_attr( $class_name ) . '"' . $data_id . '>' . $this->render_content() . '</div>'; ``` **Fixed Code:** ```php // Line 31 - Ensure render_icon() returns escaped output or escape the result return '<div class="close-icon">' . wp_kses_post( $this->render_icon( $close_icon_type, $close_icon, $close_icon_svg ) ) . '</div>'; // Lines 89-90 - Already properly escaped with esc_attr() $id_attr = ! empty( $anchor ) ? ' id="' . esc_attr( $anchor ) . '"' : ''; $data_id = ' data-id="' . esc_attr( $id_parts[1] ) . '"'; // Line 92 - The render_content() output should be escaped or use wp_kses_post() $content = '<div' . $id_attr . ' class="' . esc_attr( $class_name ) . '"' . $data_id . '>' . wp_kses_post( $this->render_content() ) . '</div>'; ``` **Issue:** The `render_icon()` method's output and `render_content()` method's output are not verified to be escaped before being concatenated into HTML. If these methods return user-controlled or unfiltered data, they could introduce XSS vulnerabilities. Additionally, the `render_content()` method outputs HTML attributes without full context validation.
CVE Analysis Results:
CVE-2026-2868: Yes
View CVE Description
The Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'separatorIconSVG' parameter in versions up to, and including, 3.5.3 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
lib/framework/includes/block/class-section.php
AI: 4 vulnerabilities
CVE-2026-2868
--- /dev/null+++ cache/gutenverse_3.6.0/lib/framework/includes/block/class-section.php@@ -0,0 +1,1051 @@+<?php+/**+ * Section Block class+ *+ * @author Jegstudio+ * @since 1.0.0+ * @package gutenverse-framework\block+ */++namespace Gutenverse\Framework\Block;++/**+ * Class Section Block+ *+ * @package gutenverse-framework\block+ */+class Section extends Block_Abstract {++ /**+ * Check if sticky is active.+ *+ * @param array $sticky Sticky attribute.+ * @return bool+ */+ private function is_sticky( $sticky ) {+ if ( empty( $sticky ) || ! is_array( $sticky ) ) {+ return false;+ }+ foreach ( $sticky as $value ) {+ if ( $value ) {+ return true;+ }+ }+ return false;+ }++ /**+ * Check if background animation is active.+ *+ * @param array $animation Background animated attribute.+ * @return bool+ */+ private function is_animation_active( $animation ) {+ return ! empty( $animation ) && isset( $animation['actions'] ) && is_array( $animation['actions'] ) && count( $animation['actions'] ) > 0;+ }++ /**+ * Check if value is empty (mirrors JS isEmptyValue).+ *+ * @param mixed $value Value to check.+ * @return bool+ */+ private function is_empty_value( $value ) {+ if ( empty( $value ) ) {+ return true;+ }+ if ( is_array( $value ) && isset( $value['type'] ) && 'variable' === $value['type'] ) {+ return true;+ }+ return false;+ }++ /**+ * Get data ID from element ID.+ *+ * @return string+ */+ private function get_data_id() {+ $element_id = $this->get_element_id();+ $parts = explode( '-', $element_id );+ return isset( $parts[1] ) ? $parts[1] : '';+ }++ /**+ * Render advance animation data attributes.+ *+ * @return string+ */+ private function render_advance_animation_data() {+ if ( isset( $this->attributes['advanceAnimation']['type'] ) && ! empty( $this->attributes['advanceAnimation']['type'] ) ) {+ $data_id = $this->get_data_id();+ if ( ! empty( $data_id ) ) {+ return ' data-id="' . esc_attr( $data_id ) . '"';+ }+ }+ return '';+ }++ /**+ * Render guten-data div with JSON data attributes.+ *+ * @param string $data_id Data ID.+ * @param bool $is_sticky Is sticky active.+ * @param bool $is_bg_animated Is background animated active.+ * @param bool $is_top_div_animated Is top divider animated.+ * @param bool $is_bottom_div_animated Is bottom divider animated.+ * @param bool $is_slideshow Is slideshow active.+ * @return string+ */+ private function render_guten_data( $data_id, $is_sticky, $is_bg_animated, $is_top_div_animated, $is_bottom_div_animated, $is_slideshow ) {+ if ( ! $is_sticky && ! $is_bg_animated && ! $is_top_div_animated && ! $is_bottom_div_animated && ! $is_slideshow ) {+ return '';+ }++ $output = '<div class="guten-data">';++ $json_flags = JSON_UNESCAPED_SLASHES;++ if ( $is_sticky ) {+ $sticky_data = array(+ 'sticky' => isset( $this->attributes['sticky'] ) ? $this->attributes['sticky'] : new \stdClass(),+ 'stickyShowOn' => isset( $this->attributes['stickyShowOn'] ) ? $this->attributes['stickyShowOn'] : 'both',+ 'stickyPosition' => isset( $this->attributes['stickyPosition'] ) ? $this->attributes['stickyPosition'] : 'top',+ 'stickyEase' => isset( $this->attributes['stickyEase'] ) ? $this->attributes['stickyEase'] : 'none',+ 'stickyDuration' => isset( $this->attributes['stickyDuration'] ) ? $this->attributes['stickyDuration'] : 0.25,+ 'topSticky' => isset( $this->attributes['topSticky'] ) ? $this->attributes['topSticky'] : new \stdClass(),+ 'bottomSticky' => isset( $this->attributes['bottomSticky'] ) ? $this->attributes['bottomSticky'] : new \stdClass(),+ );+ $output .= '<div data-var="stickyData' . esc_attr( $data_id ) . '" data-value="' . esc_attr( wp_json_encode( $sticky_data, $json_flags ) ) . '"></div>';+ }++ if ( $is_bg_animated ) {+ $bg_animated = isset( $this->attributes['backgroundAnimated'] ) ? $this->attributes['backgroundAnimated'] : new \stdClass();+ $output .= '<div data-var="bgAnimatedData' . esc_attr( $data_id ) . '" data-value="' . esc_attr( wp_json_encode( $bg_animated, $json_flags ) ) . '"></div>';+ }++ if ( $is_top_div_animated ) {+ $top_div_animated = isset( $this->attributes['topDividerAnimated'] ) ? $this->attributes['topDividerAnimated'] : new \stdClass();+ $output .= '<div data-var="topDividerAnimatedData' . esc_attr( $data_id ) . '" data-value="' . esc_attr( wp_json_encode( $top_div_animated, $json_flags ) ) . '"></div>';+ }++ if ( $is_bottom_div_animated ) {+ $bottom_div_animated = isset( $this->attributes['bottomDividerAnimated'] ) ? $this->attributes['bottomDividerAnimated'] : new \stdClass();+ $output .= '<div data-var="bottomDividerAnimatedData' . esc_attr( $data_id ) . '" data-value="' . esc_attr( wp_json_encode( $bottom_div_animated, $json_flags ) ) . '"></div>';+ }++ if ( $is_slideshow ) {+ $background = isset( $this->attributes['background'] ) ? $this->attributes['background'] : array();+ $slide_image = isset( $background['slideImage'] ) ? $background['slideImage'] : array();+ $slide_data = $background;+ unset( $slide_data['slideImage'] );+ $slide_data['slideLength'] = is_array( $slide_image ) ? count( $slide_image ) : 0;+ $output .= '<div data-var="backgroundSlideshow' . esc_attr( $data_id ) . '" data-value="' . esc_attr( wp_json_encode( $slide_data, $json_flags ) ) . '"></div>';+ }++ $output .= '</div>';++ return $output;+ }++ /**+ * Render slideshow elements.+ *+ * @return string+ */+ private function render_slide_elements() {+ $background = isset( $this->attributes['background'] ) ? $this->attributes['background'] : array();+ $slide_image = isset( $background['slideImage'] ) ? $background['slideImage'] : array();+ $element_id = $this->get_element_id();++ if ( empty( $slide_image ) || ! is_array( $slide_image ) ) {+ return '';+ }++ $output = '<div class="bg-slideshow-container">';+ $output .= '<div class="bg-slideshow-item">';++ foreach ( $slide_image as $index => $image ) {+ $image_url = '';+ if ( isset( $image['image']['image'] ) && ! empty( $image['image']['image'] ) ) {+ $image_url = $image['image']['image'];+ }++ $slide_class = $element_id . '-slideshow-image slideshow-image';+ if ( 1 === $index ) {+ $slide_class .= ' current';+ } elseif ( 0 === $index ) {+ $slide_class .= ' previous';+ }++ $style_attr = ! empty( $image_url ) ? ' style="background-image: url(' . esc_url( $image_url ) . ')"' : '';++ $output .= '<div class="' . esc_attr( $element_id . '-child-slideshow slideshow-item-container item-' . $index ) . '">';+ $output .= '<div class="' . esc_attr( $slide_class ) . '"' . $style_attr . '></div>';+ $output .= '</div>';+ }++ $output .= '</div>';+ $output .= '</div>';++ return $output;+ }++ /**+ * Render video background container.+ *+ * @return string+ */+ private function render_video_container() {+ $background = isset( $this->attributes['background'] ) ? $this->attributes['background'] : array();++ if ( ! isset( $background['type'] ) || 'video' !== $background['type'] ) {+ return '';+ }++ $video_link = isset( $background['videoLink'] ) ? $background['videoLink'] : '';++ if ( empty( $video_link ) ) {+ return '';+ }++ $player_vars = array(+ 'showinfo' => 0,+ );++ $video_start = ! empty( $background['videoStartTime'] ) ? intval( $background['videoStartTime'] ) : 0;+ $video_end = ! empty( $background['videoEndTime'] ) ? intval( $background['videoEndTime'] ) : 0;++ if ( $video_start > 0 ) {+ $player_vars['start'] = $video_start;+ }++ if ( $video_end > 0 ) {+ $player_vars['end'] = $video_end;+ }++ $config = (object) array(+ 'youtube' => (object) array(+ 'playerVars' => (object) $player_vars,+ ),+ );++ $data_properties = (object) array(+ 'url' => $video_link,+ 'class' => 'guten-video-bg-wrapper' . ( ! empty( $background['videoPlayOnMobile'] ) ? ' show-phone' : '' ),+ 'width' => '100%',+ 'height' => '100%',+ 'playing' => true,+ 'muted' => true,+ 'loop' => ! ( isset( $background['videoPlayOnce'] ) && $background['videoPlayOnce'] ),+ 'playsinline' => true,+ 'style' => (object) array(+ 'zIndex' => 0,+ 'top' => 0,+ 'left' => 0,+ 'position' => 'absolute',+ 'overflow' => 'hidden',+ 'pointerEvents' => 'none',+ ),+ 'config' => $config,+ );++ return '<div class="guten-video-background" data-property="' . esc_attr( wp_json_encode( $data_properties, JSON_UNESCAPED_SLASHES ) ) . '"></div>';+ }++ /**+ * Render gradient SVG element.+ *+ * @param string $id Gradient ID.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @return string+ */+ private function render_gradient_svg( $id, $gradient_color, $gradient_angle = null ) {+ if ( empty( $gradient_color ) || ! is_array( $gradient_color ) ) {+ return '';+ }++ $stops = '';+ foreach ( $gradient_color as $color_stop ) {+ $color = isset( $color_stop['color'] ) ? $color_stop['color'] : '#000';+ $offset = isset( $color_stop['offset'] ) ? ( floatval( $color_stop['offset'] ) * 100 ) : 0;+ $stops .= '<stop style="stop-color:' . esc_attr( $color ) . '" offset="' . esc_attr( $offset ) . '%"></stop>';+ }++ $transform = '';+ if ( $gradient_angle ) {+ $transform = ' gradientTransform="rotate(' . esc_attr( $gradient_angle ) . ')"';+ }++ return '<linearGradient id="' . esc_attr( $id ) . '"' . $transform . '>' . $stops . '</linearGradient>';+ }++ /**+ * Render shape divider SVG based on type.+ *+ * @param string $id Divider ID.+ * @param string $type Divider type.+ * @param bool $invert Invert divider.+ * @param bool $gradient Use gradient.+ * @param array $props Additional properties.+ * @return string+ */+ private function render_shape_divider_svg( $id, $type, $invert, $gradient, $props ) {+ $gradient_color = isset( $props['gradientColor'] ) ? $props['gradientColor'] : array();+ $gradient_angle = isset( $props['gradientAngle'] ) ? $props['gradientAngle'] : null;+ $gradient_color2 = isset( $props['gradientColor2'] ) ? $props['gradientColor2'] : array();+ $gradient_angle2 = isset( $props['gradientAngle2'] ) ? $props['gradientAngle2'] : null;+ $gradient_color3 = isset( $props['gradientColor3'] ) ? $props['gradientColor3'] : array();+ $gradient_angle3 = isset( $props['gradientAngle3'] ) ? $props['gradientAngle3'] : null;++ switch ( $type ) {+ case 'arrow':+ return $this->render_single_path_svg( $id, '0 0 1200 10', '1200', '10', $invert ? 'M 0,10 V 0 H 600 L 590,10 Z M 600,0 h 600 V 10 H 610 Z' : 'm600 10-10-10h20z', $gradient, $gradient_color, $gradient_angle );++ case 'curve':+ return $this->render_single_path_svg( $id, '0 0 1200 100', '1200', '100', $invert ? 'M 0,100 V 0 H 600 C 339.74,0 113.72,40.53 0,100 Z M 600,0 h 600 V 100 C 1086.28,40.53 860.26,0 600,0 Z' : 'm1200 0c-113.72 59.47-339.74 100-600 100s-486.28-40.53-600-100z', $gradient, $gradient_color, $gradient_angle );++ case 'curve_a1':+ return $this->render_triple_layer_svg( $id, '0 0 1200 165', '1200', '165', 'm1200 0v16c-163.37 62.074-429.49 110-730 110-172.25 0-333.2-13.229-470-36.2919v-89.7081z', 'm1200 0v16c-163.37 52.221-429.49 90-730 90-172.25 0-333.2-11.1293-470-30.5313v-75.4687z', 'm1200 0v16c-163.37 42.23-429.49 69.72-730 69.72-172.25 0-333.2-9-470-24.69v-61.03z', $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );++ case 'curve_a2':+ return $this->render_single_path_svg( $id, '0 0 1200 86', '1200', '86', $invert ? 'M 1200,70 C 1036.63,27.77 770.51,0.279297 470,0.279297 297.75,0.279297 136.8,9.280703 0,24.970703 V 0 h 1200 z' : 'm1200 0v16c-163.37 42.23-429.49 69.72-730 69.72-172.25 0-333.2-9-470-24.69v-61.03z', $gradient, $gradient_color, $gradient_angle );++ case 'curve_n':+ return $this->render_triple_layer_svg( $id, '0 0 1200 188', '1200', '188', 'm1200 0v27.1567c-13.33-.0847-26.7-.1271-40.1-.1271-555.19 0-1022.39 68.2793-1159.9 160.9704v-188z', 'm1200 0v24.2677c-13.33-.0757-26.7-.1136-40.1-.1136-555.19 0-1022.39 61.0155-1159.9 143.8459v-168z', 'm1200 0v21.37c-13.33-.0667-26.7-.1-40.1-.1-555.19 0-1022.39 53.73-1159.9 126.67v-147.94z', $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );++ case 'curve_o':+ return $this->render_curve_opacity_svg( $id, $invert, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );++ case 'mountain':+ return $this->render_single_path_svg( $id, '0 0 1200 208', '1200', '208', $invert ? 'M 1200,180 900,36 600,144 300,36 0,0 h 1200 z' : 'm0 208 300-36 300-108 300 108 300-144v-28h-300-300-300-300z', $gradient, $gradient_color, $gradient_angle );++ case 'mountain_o':+ return $this->render_mountain_opacity_svg( $id, $invert, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );++ case 'papertear':+ return $this->render_papertear_svg( $id, $invert, $gradient, $gradient_color, $gradient_angle );++ case 'split':+ return $this->render_single_path_svg( $id, '0 0 1200 50', '1200', '50', 'm650 0c-13.261 0-25.978 5.26784-35.355 14.6447-9.377 9.3768-14.645 22.0945-14.645 35.3553-.029-13.2418-5.31-25.9312-14.683-35.2843-9.374-9.35299-22.075-14.605732-35.317-14.6057v-.11z', $gradient, $gradient_color, $gradient_angle );++ case 'split_n':+ return $this->render_split_negative_svg( $id, $gradient, $gradient_color, $gradient_angle );++ case 'tilt':+ return $this->render_single_path_svg( $id, '0 0 1200 111', '1200', '111', 'M1200 0V5.61L0 110.59V0H1200Z', $gradient, $gradient_color, $gradient_angle );++ case 'tilt_g':+ return $this->render_tilt_gradient_svg( $id, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );++ case 'triangle':+ return $this->render_triangle_svg( $id, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );++ case 'triangle_2':+ return $this->render_single_path_svg( $id, '0 0 1200 100', '1200', '100', 'm600 100-600-100h1200z', $gradient, $gradient_color, $gradient_angle );++ case 'triangle_3':+ return $this->render_single_path_svg( $id, '0 0 1200 100', '1200', '100', $invert ? 'M 0,100 V 0 H 376 Z M 376,0 h 824 v 100 z' : 'm376 100-376-100h1200z', $gradient, $gradient_color, $gradient_angle );++ case 'triangle_o':+ return $this->render_triple_layer_svg( $id, '0 0 1200 100', '1200', '100', 'm1200 0h-1200v40l376 60 824-60z', 'm1200 0h-1200v20l376 80 824-80z', 'm376 100-376-100h1200z', $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );++ case 'triangle_n':+ return $this->render_single_path_svg( $id, '0 0 1200 100', '1200', '100', 'm1200 0v100l-600-95-600 95v-100z', $gradient, $gradient_color, $gradient_angle );++ case 'triangle_n_o':+ return $this->render_triple_layer_svg( $id, '0 0 1200 100', '1200', '100', 'm1200 0v100l-600-95-600 95v-100z', 'm1200 0v80l-600-75-600 75v-80z', 'm1200 0v60l-600-55-600 55v-60z', $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );++ case 'waves':+ return $this->render_single_path_svg_with_clip_rule( $id, '0 0 1200 143', '1200', '143', $invert ? 'm 1167.0001,143 c -34,0 -100,-6.3e-4 -167,-27.97892 C 933.00001,87.042746 867,31.087613 800,10.103956 733.00001,-10.879706 667.00001,3.1082614 600,31.086478 532.99999,59.064801 467,101.03387 400,122.01753 c -67,20.98379 -133,20.98379 -200,0 C 133,101.03387 67,59.064422 33,38.080645 L 0,17.098123 V 0 h 1200 v 143 z' : 'm1200 20.0467h-33c-34 0-100 0-167 24.0561s-133 72.1682-200 90.2102-133 6.014-200-18.042c-67-24.0561-133-60.1402-200-78.1822-67-18.0421-133-18.0421-200 0-67 18.042-133 54.1261-167 72.1682l-33 18.042v-128.299h1200z', $gradient, $gradient_color, $gradient_angle );++ case 'waves_2':+ return $this->render_single_path_svg( $id, '0 0 1200 191', '1200', '191', $invert ? 'm 1200,174 -50,-18 C 1100,138 1000,102 900,90 855.556,84.667 811.11197,84.07347 766.66797,83.48047 711.11197,82.74047 655.556,82 600,72 561.538,65.077 523.07723,53.71647 484.61523,42.35547 423.07723,24.17847 361.538,6 300,6 200,6 100,54 50,78 L 0,102 V 0 h 1200 z' : 'm1200 0h-1200v89l50 24c50 24 150 72 250 72 61.538 0 123.077-18.178 184.615-36.355 38.462-11.361 76.923-22.722 115.385-29.645 55.556-10 111.111-10.741 166.667-11.481 44.444-.593 88.889-1.186 133.333-6.519 100-12 200-48 250-66l50-18z', $gradient, $gradient_color, $gradient_angle );++ case 'waves_o1':+ return $this->render_waves_o1_svg( $id, $invert, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );++ case 'waves_o2':+ return $this->render_waves_o2_svg( $id, $invert, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );++ case 'waves_o3':+ return $this->render_waves_o3_svg( $id, $invert, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );++ case 'zigzag':+ return $this->render_zigzag_svg( $id, $gradient, $gradient_color, $gradient_angle );++ default:+ return '';+ }+ }++ /**+ * Render single path SVG.+ *+ * @param string $id Gradient ID.+ * @param string $viewbox ViewBox attribute.+ * @param string $width Width.+ * @param string $height Height.+ * @param string $d Path data.+ * @param bool $gradient Use gradient.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @return string+ */+ private function render_single_path_svg( $id, $viewbox, $width, $height, $d, $gradient, $gradient_color, $gradient_angle ) {+ $fill = ( $gradient && ! empty( $gradient_color ) ) ? 'url(#' . esc_attr( $id ) . ')' : '#000';+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- SVG path data is hardcoded.+ $svg = '<svg class="guten-shape-fill" viewBox="' . esc_attr( $viewbox ) . '" preserveAspectRatio="none" fill="none" height="' . esc_attr( $height ) . '" width="' . esc_attr( $width ) . '" xmlns="http://www.w3.org/2000/svg">';+ $svg .= '<path d="' . $d . '" fill="' . esc_attr( $fill ) . '"/>';+ if ( $gradient && ! empty( $gradient_color ) ) {+ $svg .= $this->render_gradient_svg( $id, $gradient_color, $gradient_angle );+ }+ $svg .= '</svg>';+ return $svg;+ }++ /**+ * Render single path SVG with clip rule.+ *+ * @param string $id Gradient ID.+ * @param string $viewbox ViewBox attribute.+ * @param string $width Width.+ * @param string $height Height.+ * @param string $d Path data.+ * @param bool $gradient Use gradient.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @return string+ */+ private function render_single_path_svg_with_clip_rule( $id, $viewbox, $width, $height, $d, $gradient, $gradient_color, $gradient_angle ) {+ $fill = ( $gradient && ! empty( $gradient_color ) ) ? 'url(#' . esc_attr( $id ) . ')' : '#000';+ $svg = '<svg fill="none" height="' . esc_attr( $height ) . '" class="guten-shape-fill" viewBox="' . esc_attr( $viewbox ) . '" preserveAspectRatio="none" width="' . esc_attr( $width ) . '" xmlns="http://www.w3.org/2000/svg">';+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- SVG path data is hardcoded.+ $svg .= '<path clip-rule="evenodd" d="' . $d . '" fill-rule="evenodd" fill="' . esc_attr( $fill ) . '"/>';+ if ( $gradient && ! empty( $gradient_color ) ) {+ $svg .= $this->render_gradient_svg( $id, $gradient_color, $gradient_angle );+ }+ $svg .= '</svg>';+ return $svg;+ }++ /**+ * Render triple layer SVG (for shapes with 3 opacity layers).+ *+ * @param string $id Gradient ID.+ * @param string $viewbox ViewBox attribute.+ * @param string $width Width.+ * @param string $height Height.+ * @param string $d1 Path data layer 1.+ * @param string $d2 Path data layer 2.+ * @param string $d3 Path data layer 3.+ * @param bool $gradient Use gradient.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @param array $gradient_color2 Gradient color stops 2.+ * @param mixed $gradient_angle2 Gradient angle 2.+ * @param array $gradient_color3 Gradient color stops 3.+ * @param mixed $gradient_angle3 Gradient angle 3.+ * @return string+ */+ private function render_triple_layer_svg( $id, $viewbox, $width, $height, $d1, $d2, $d3, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 ) {+ $svg = '<svg fill="none" height="' . esc_attr( $height ) . '" class="guten-shape-fill" viewBox="' . esc_attr( $viewbox ) . '" preserveAspectRatio="none" width="' . esc_attr( $width ) . '" xmlns="http://www.w3.org/2000/svg">';++ if ( $gradient ) {+ $fill1 = ! empty( $gradient_color ) ? 'url(#' . esc_attr( $id ) . ')' : '#00000044';+ $fill2 = ! empty( $gradient_color2 ) ? 'url(#' . esc_attr( $id ) . '-2)' : '#00000088';+ $fill3 = ! empty( $gradient_color3 ) ? 'url(#' . esc_attr( $id ) . '-3)' : '#000';+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- SVG path data is hardcoded.+ $svg .= '<g>';+ $svg .= '<path d="' . $d1 . '" opacity=".25" fill="' . esc_attr( $fill1 ) . '"/>';+ $svg .= '<path d="' . $d2 . '" opacity=".5" fill="' . esc_attr( $fill2 ) . '"/>';+ $svg .= '<path d="' . $d3 . '" fill="' . esc_attr( $fill3 ) . '"/>';+ $svg .= '</g>';+ if ( ! empty( $gradient_color ) ) {+ $svg .= $this->render_gradient_svg( $id, $gradient_color, $gradient_angle );+ }+ if ( ! empty( $gradient_color2 ) ) {+ $svg .= $this->render_gradient_svg( $id . '-2', $gradient_color2, $gradient_angle2 );+ }+ if ( ! empty( $gradient_color3 ) ) {+ $svg .= $this->render_gradient_svg( $id . '-3', $gradient_color3, $gradient_angle3 );+ }+ } else {+ $svg .= '<g fill="#000">';+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- SVG path data is hardcoded.+ $svg .= '<path d="' . $d1 . '" opacity=".25"/>';+ $svg .= '<path d="' . $d2 . '" opacity=".5"/>';+ $svg .= '<path d="' . $d3 . '"/>';+ $svg .= '</g>';+ }++ $svg .= '</svg>';+ return $svg;+ }++ /**+ * Render curve opacity SVG.+ *+ * @param string $id Gradient ID.+ * @param bool $invert Invert.+ * @param bool $gradient Use gradient.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @param array $gradient_color2 Gradient color stops 2.+ * @param mixed $gradient_angle2 Gradient angle 2.+ * @param array $gradient_color3 Gradient color stops 3.+ * @param mixed $gradient_angle3 Gradient angle 3.+ * @return string+ */+ private function render_curve_opacity_svg( $id, $invert, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 ) {+ if ( $invert ) {+ $d1 = 'M 0,100 V 0 H 1200 V 100 C 1086.28,64.318 860.26,40 600,40 339.74,40 113.72,64.318 0,100 Z';+ $d2 = 'M 0,100 V 0 H 1200 V 100 C 1086.28,52.424 860.26,20 600,20 339.74,20 113.72,52.424 0,100 Z';+ $d3 = 'M 0,100 V 0 H 600 C 339.74,0 113.72,40.53 0,100 Z M 600,0 h 600 V 100 C 1086.28,40.53 860.26,0 600,0 Z';+ } else {+ $d1 = 'm1200 0c-113.72 59.47-339.74 100-600 100s-486.28-40.53-600-100z';+ $d2 = 'm1200 0c-113.72 47.576-339.74 80-600 80s-486.28-32.424-600-80z';+ $d3 = 'm1200 0c-113.72 35.682-339.74 60-600 60s-486.28-24.318-600-60z';+ }++ return $this->render_triple_layer_svg( $id, '0 0 1200 100', '1200', '100', $d1, $d2, $d3, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );+ }++ /**+ * Render mountain opacity SVG.+ *+ * @param string $id Gradient ID.+ * @param bool $invert Invert.+ * @param bool $gradient Use gradient.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @param array $gradient_color2 Gradient color stops 2.+ * @param mixed $gradient_angle2 Gradient angle 2.+ * @param array $gradient_color3 Gradient color stops 3.+ * @param mixed $gradient_angle3 Gradient angle 3.+ * @return string+ */+ private function render_mountain_opacity_svg( $id, $invert, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 ) {+ if ( $invert ) {+ $d1 = 'M 1200,230 900,86 600,194 300,86 0,50 V 0 h 1200 z';+ $d2 = 'M 1200,230 904,63.5 600,194 300,63.5 0,20 V 0 h 1200 z';+ $d3 = 'M 1200,230 909,44.5 600,194 301,43.5 0,0 h 1200 z';+ } else {+ $d1 = 'm0 258 301-43.5 299-150.5 309 149.5 291-185.5v-28h-1200z';+ $d2 = 'm0 238 300-43.5 300-130.5 304 130.5 296-166.5v-28h-1200z';+ $d3 = 'm0 208 300-36 300-108 300 108 300-144v-28h-300-300-300-300z';+ }++ $viewbox = $invert ? '0 0 1200 230' : '0 0 1200 258';+ $height = $invert ? '230' : '258';++ return $this->render_triple_layer_svg( $id, $viewbox, '1200', $height, $d1, $d2, $d3, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );+ }++ /**+ * Render papertear SVG.+ *+ * @param string $id Gradient ID.+ * @param bool $invert Invert.+ * @param bool $gradient Use gradient.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @return string+ */+ private function render_papertear_svg( $id, $invert, $gradient, $gradient_color, $gradient_angle ) {+ if ( $invert ) {+ // phpcs:ignore Generic.Files.LineLength.TooLong -- SVG path data.+ $d = 'M 0,51 V 50.94922 H 1199.8496 L 1200,37.058594 V 51 Z M 1038.3262,36.029297 c -1.7416,0.11375 -3.5646,-0.267969 -5.5371,-1.480469 -2.89,-1 -7.57,0.580391 -10,-1.849609 -4.14,-4 -9.89,-4.721407 -14.5,-7.691407 -3.44,-2.219999 -6.9389,-3.058984 -10.12894,0.541016 -0.72,0.81 -1.68055,0.660078 -2.56055,0.580078 -3.553,-0.235 -7.11692,-0.235 -10.66992,0 -5.31,1.07 -9.76891,-3.320468 -15.12891,-1.480468 -3.44,0.67 -6.72164,2.250078 -10.43164,1.080078 -3.22,-0.47 -6.26851,5.999609 -9.22852,1.349609 -3.05999,-2.89 -7.93124,-2.289766 -11.78124,-3.509766 -2.08001,-0.44 -3.99938,-0.86 -5.85938,1 -1.49,1.42 -3.63086,0.729922 -5.13086,-0.330078 -9.93,-7.13 -14.94,9.88 -32,5.25 -3.47,-0.74 -6.99859,-1.349219 -10.55859,-0.199219 -5.442,-1.776199 -11.32417,-1.675037 -16.70117,0.289063 -5.59001,1.7 -11.1286,3.059609 -17.0586,1.599609 -2.74,-0.68 -5.53,0.211641 -8,1.431641 -13.21,7.6 -25.00117,-7.841797 -33.20117,-3.841797 -5.62,5.19 -9.39,-10.868437 -24,-8.898437 -6.37,0 -13.29008,2.13875 -19.08008,-1.53125 -1.05,-0.6429 -2.21855,-1.068407 -3.43555,-1.253907 -1.218,-0.1855 -2.46029,-0.127172 -3.65429,0.173828 -8.43,1.66 -16.74938,2.391563 -25.35938,0.601563 -7.39,-1.54 -14.99953,-0.281641 -22.51953,0.06836 -8.53,0.35 -11.60117,-6.209453 -16.95117,4.310547 -5.82,10.41 -12.11039,0.690547 -19.40039,-1.939453 -7.21,-3.75 -13.51828,2.770234 -20.73828,1.490234 -11.11,-2.9 -14.94008,3.999141 -22.58008,-0.380859 -5.52,-2.18 -11.00102,-7.36 -17.29102,-5 -2.46,1 -2.65015,-2.129922 -4.41015,-2.419922 -1.64,2.91 -1.54977,2.840391 -3.75977,0.150391 -4.26,-4.55 -11.06062,-0.830781 -16.14062,-3.800781 -0.175,-0.0814 -0.3656,-0.123047 -0.5586,-0.123047 -0.193,0 -0.38554,0.04165 -0.56054,0.123047 -3.49,2.1 -7.12922,1.150234 -10.69922,0.490234 -6.08,-1.14 -11.41016,13.58 -22.16016,9 -2,-0.76 -4.00133,0.09 -5.86133,1 -2.94,1.37 -5.49883,2.001094 -8.79883,-0.128906 -2.15999,-1.37 -5.67124,-0.520157 -8.53124,-0.910157 -2.86001,-0.39 -4.30907,2.420001 -6.28907,3 -11.05,5.620001 -22.21117,12.149922 -35.20117,10.419922 -1.73,-0.66 -3.61,2.13875 -5,0.21875 -4,-4.25 -9.19969,-2.810156 -13.92969,-2.660156 -6.33,1.1 -12.44867,-3.509687 -18.38867,0.07031 -5.24,2 -10.29148,-7.568438 -15.27148,-2.148438 -2.77,2.24 -7.65868,5.54961 -10.88868,2.599609 -2.87999,-2.929999 -6.75156,-4.460078 -9.85156,-7.080078 -1,-0.83 -2.04828,-1.329765 -3.23828,-0.259765 -6.44,-0.62 -13.21023,1.538437 -19.74023,-0.351563 -4.35,-1.14 -8.00125,1.880938 -12.78125,-0.789062 -7.87,-3.74 -7.86985,2.150625 -11.08985,-1.109375 -3,-3.21 -4.87867,-8.69 -10.13867,-8 -8.67,1 -17.29125,-0.400469 -25.78125,1.519531 -3.91,1.7 -1.43969,13.469063 -12.92969,7.789062 -3.67,-2.399999 -7.73945,0.671251 -11.68945,-1.21875 -6.1,-2.66 -10.07078,3.618907 -15.55078,1.378907 -0.341,-0.2091 -0.74167,-0.2972 -1.13867,-0.25 -0.397,0.0472 -0.76778,0.226565 -1.05078,0.509765 -5,4.11 -10.6911,4.360782 -16.6211,2.550782 -18.12,-8.55 -8.70937,8.000234 -29.85937,-4.759766 -8.78,-6 -15.90938,-0.229844 -24.35938,-2.589844 -2.59,-0.63 -2.52945,6.369532 -7.43945,3.269532 -0.39,-0.260001 -1.15016,-0.539375 -1.41016,-0.359376 -3.38,2.390001 -7.66007,0.08016 -11.08008,2.160157 -0.53999,0.33 -1.41117,0.369375 -1.70117,-0.140625 -1.42,-4.13 -17.33015,3.570312 -27.16015,-6.429688 -6,-4.18 -17.1886,3.05875 -25.8086,-1.78125 -4.76,-2.23 -9.70015,-1.77 -14.66015,-1 -11.55,4.49 -16.00024,-3.529062 -26.24024,-2.539062 -4.51,0.28 -7.889685,-3.789688 -12.429685,-3.679688 -1.07,0 -1.550703,-0.890703 -2.220703,-1.470703 -2.07,-1.8 -4.63,-2.869375 -7,-1.609375 -7.66,3.97 -15.830625,2.900391 -23.890625,2.900391 -3.92,-0.74 -14.779453,2 -16.439453,-2 -3,-5.59 -3.090235,-5.551407 -9.490235,-4.691407 -0.4,0.05 -0.999453,0.250313 -1.189453,0.070313 -3,-2.79 -5.13039,-0.369297 -7.40039,1.220703 -3.37,2.76 -7.1,-1.769922 -9,4.330078 -0.24,0.86 -0.999766,0.29 -1.509766,0 -4.22,-3 -9.8,0.890391 -13.25,-4.099609 C 2.64,1.959297 1.2503125,1.919375 0.0703125,2.109375 H 0 V 0 h 1200 v 23.183594 c -1.8897,-0.174264 -3.7883,5.28e-4 -5.5996,0.574218 -4.46,1 -8.9,-0.08945 -13.25,-1.189453 -5,-2.14 -10.5313,-0.310547 -15.5313,-2.310547 -12.72,-5.789999 -18.7698,5.091563 -28.5898,1.351563 -10.2,3.9 -20.6994,4.12 -30.6094,-1 -8.81,-4.21 -19.3204,7.769531 -29.4004,7.769531 -7.76,0.91 -15.4798,2.490235 -23.3398,2.240235 -5.6325,0.2625 -10.1288,5.068906 -15.3535,5.410156 z';+ } else {+ // phpcs:ignore Generic.Files.LineLength.TooLong -- SVG path data.+ $d = 'm1200.29 27.78c-1.94.1999-3.89-.0009-5.75-.59-4.46-1-8.9.09-13.25 1.19-5 2.14-10.53.31-15.53 2.31-12.72 5.79-18.77-5.09-28.59-1.35-10.2-3.9-20.7-4.12-30.61 1-8.81 4.21-19.32-7.77-29.4-7.77-7.76-.91-15.48-2.49-23.34-2.24-7.51-.35-13-8.78-20.89-3.93-2.89 1-7.57-.58-10 1.85-4.14 4-9.89 4.72-14.5 7.69-3.44 2.22-6.94 3.06-10.13-.54-.72-.81-1.68-.66-2.56-.58-3.553.235-7.117.235-10.67 0-5.31-1.07-9.77 3.32-15.13 1.48-3.44-.67-6.72-2.25-10.43-1.08-3.22.47-6.27-6-9.23-1.35-3.06 2.89-7.93 2.29-11.78 3.51-2.08.44-4 .86-5.86-1-1.49-1.42-3.63-.73-5.13.33-9.93 7.13-14.94-9.88-32-5.25-3.47.74-7 1.35-10.56.2-5.442 1.7762-11.323 1.6741-16.7-.29-5.59-1.7-11.13-3.06-17.06-1.6-2.74.68-5.53-.21-8-1.43-13.21-7.6-25 7.84-33.2 3.84-5.62-5.19-9.39 10.87-24 8.9-6.37 0-13.29-2.14-19.08 1.53-1.05.6429-2.219 1.0696-3.436 1.2551-1.218.1855-2.46.1259-3.654-.1751-8.43-1.66-16.75-2.39-25.36-.6-7.39 1.54-15 .28-22.52-.07-8.53-.35-11.6 6.21-16.95-4.31-5.82-10.41-12.11-.69-19.4 1.94-7.21 3.75-13.52-2.77-20.74-1.49-11.11 2.9-14.94-4-22.58.38-5.52 2.18-11 7.36-17.29 5-2.46-1-2.65 2.13-4.41 2.42-1.64-2.91-1.55-2.84-3.76-.15-4.26 4.55-11.06.83-16.14 3.8-.175.0814-.367.1236-.56.1236s-.385-.0422-.56-.1236c-3.49-2.1-7.13-1.15-10.7-.49-6.08 1.14-11.41-13.58-22.16-9-2 .76-4-.09-5.86-1-2.94-1.37-5.5-2-8.8.13-2.16 1.37-5.67.52-8.53.91s-4.31-2.42-6.29-3-11.05-5.62-22.21-12.15-35.2-10.42-1.73.66-3.61-2.14-5-.22-4 4.25-9.2 2.81-13.93 2.66-6.33-1.1-12.45 3.51-18.39-.07-5.24-2-10.29 7.57-15.27 2.15-2.77-2.24-7.66-5.55-10.89-2.6-2.88 2.93-6.75 4.46-9.85 7.08-1 .83-2.05 1.33-3.24.26-6.44.62-13.21-1.54-19.74.35-4.35 1.14-8-1.88-12.78.79-7.87 3.74-7.87-2.15-11.09 1.11-3 3.21-4.88 8.69-10.14 8-8.67-1-17.29.4-25.78-1.52-3.91-1.7-1.44-13.47-12.93-7.79-3.67 2.4-7.74-.67-11.69 1.22-6.1 2.66-10.07-3.62-15.55-1.38-.341.2091-.743.2972-1.14.25s-.767-.2268-1.05-.51c-5-4.11-10.69-4.36-16.62-2.55-18.12 8.55-8.71-8-29.86 4.76-8.78 6-15.91.23-24.36 2.59-2.59.63-2.53-6.37-7.44-3.27-.39.26-1.15.54-1.41.36-3.38-2.39-7.66-.08-11.08-2.16-.54-.33-1.41-.37-1.7.14-1.42 4.13-17.33-3.57-27.16 6.43-6 4.18-17.19-3.06-25.81 1.78-4.76 2.23-9.7 1.77-14.66 1-11.55-4.49-16 3.53-26.24 2.54-4.51-.28-7.89 3.79-12.43 3.68-1.07 0-1.55.89-2.22 1.47-2.07 1.8-4.63 2.87-7 1.61-7.66-3.97-15.83-2.9-23.89-2.9-3.92.74-14.78-2-16.44 2-3 5.59-3.09 5.55-9.49 4.69-.4-.05-1-.25-1.19-.07-3 2.79-5.13.37-7.4-1.22-3.37-2.76-7.1 1.77-9-4.33-.24-.86-1-.29-1.51 0-4.22 3-9.80001-.89-13.25001 4.1-.61.82-2 .86-3.18.67h-.2199998v-48.84h1200.0000098z';+ }++ return $this->render_single_path_svg( $id, '0 0 1200 51', '1200', '51', $d, $gradient, $gradient_color, $gradient_angle );+ }++ /**+ * Render split negative SVG.+ *+ * @param string $id Gradient ID.+ * @param bool $gradient Use gradient.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @return string+ */+ private function render_split_negative_svg( $id, $gradient, $gradient_color, $gradient_angle ) {+ $d = 'm1200 0v57.38h-1200v-57.38h550v.11c13.242-.000032 25.943 5.25271 35.317 14.6057 9.373 9.3531 14.654 22.0425 14.683 35.2843 0-13.2608 5.268-25.9785 14.645-35.3553 9.376-9.37686 22.094-14.6447 35.355-14.6447z';+ $fill = ( $gradient && ! empty( $gradient_color ) ) ? 'url(#' . esc_attr( $id ) . ')' : '#000';+ $svg = '<svg class="guten-shape-fill" viewBox="0 0 1200 57" preserveAspectRatio="none" fill="none" height="57" width="1200" xmlns="http://www.w3.org/2000/svg" style="transform: translateX(-50%) rotate(180deg)">';+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- SVG path data is hardcoded.+ $svg .= '<path d="' . $d . '" fill="' . esc_attr( $fill ) . '"/>';+ if ( $gradient && ! empty( $gradient_color ) ) {+ $svg .= $this->render_gradient_svg( $id, $gradient_color, $gradient_angle );+ }+ $svg .= '</svg>';+ return $svg;+ }++ /**+ * Render tilt gradient SVG.+ *+ * @param string $id Gradient ID.+ * @param bool $gradient Use gradient.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @param array $gradient_color2 Gradient color stops 2.+ * @param mixed $gradient_angle2 Gradient angle 2.+ * @param array $gradient_color3 Gradient color stops 3.+ * @param mixed $gradient_angle3 Gradient angle 3.+ * @return string+ */+ private function render_tilt_gradient_svg( $id, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 ) {+ $svg = '<svg fill="none" height="231" class="guten-shape-fill" preserveAspectRatio="none" viewBox="0 0 1200 231" width="1200" xmlns="http://www.w3.org/2000/svg">';+ $svg .= '<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="0" x2="1200" y1="115.52" y2="115.52"><stop offset="0" stop-color="#fff"/><stop offset="1"/></linearGradient>';+ $svg .= '<linearGradient id="b" gradientUnits="userSpaceOnUse" x1="0" x2="1200" y1="85.41" y2="85.41"><stop offset="0" stop-color="#ccc"/><stop offset="1" stop-color="#fff"/></linearGradient>';+ $svg .= '<clipPath id="c"><path d="m0 0h1200v231h-1200z"/></clipPath>';++ if ( $gradient ) {+ $fill1 = ! empty( $gradient_color ) ? 'url(#' . esc_attr( $id ) . ')' : 'url(#a)';+ $fill2 = ! empty( $gradient_color2 ) ? 'url(#' . esc_attr( $id ) . '-2)' : 'url(#b)';+ $fill3 = ! empty( $gradient_color3 ) ? 'url(#' . esc_attr( $id ) . '-3)' : '#fff';++ $svg .= '<g>';+ $svg .= '<path d="m1200 0v126.06l-1200 104.99v-231.05z" fill="' . esc_attr( $fill1 ) . '"/>';+ $svg .= '<path d="m1200 0v65.84l-1200 104.98v-170.82z" fill="' . esc_attr( $fill2 ) . '"/>';+ $svg .= '<path d="m1200 0v5.61l-1200 104.98v-110.59z" fill="' . esc_attr( $fill3 ) . '"/>';+ $svg .= '</g>';++ if ( ! empty( $gradient_color ) ) {+ $svg .= $this->render_gradient_svg( $id, $gradient_color, $gradient_angle );+ }+ if ( ! empty( $gradient_color2 ) ) {+ $svg .= $this->render_gradient_svg( $id . '-2', $gradient_color2, $gradient_angle2 );+ }+ if ( ! empty( $gradient_color3 ) ) {+ $svg .= $this->render_gradient_svg( $id . '-3', $gradient_color3, $gradient_angle3 );+ }+ } else {+ $svg .= '<g>';+ $svg .= '<path d="m1200 0v126.06l-1200 104.99v-231.05z" fill="url(#a)"/>';+ $svg .= '<path d="m1200 0v65.84l-1200 104.98v-170.82z" fill="url(#b)"/>';+ $svg .= '<path d="m1200 0v5.61l-1200 104.98v-110.59z" fill="#fff"/>';+ $svg .= '</g>';+ }++ $svg .= '</svg>';+ return $svg;+ }++ /**+ * Render triangle SVG.+ *+ * @param string $id Gradient ID.+ * @param bool $gradient Use gradient.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @param array $gradient_color2 Gradient color stops 2.+ * @param mixed $gradient_angle2 Gradient angle 2.+ * @param array $gradient_color3 Gradient color stops 3.+ * @param mixed $gradient_angle3 Gradient angle 3.+ * @return string+ */+ private function render_triangle_svg( $id, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 ) {+ $svg = '<svg fill="none" height="100" class="guten-shape-fill" preserveAspectRatio="none" viewBox="0 0 1200 100" width="1200" xmlns="http://www.w3.org/2000/svg">';++ if ( $gradient && ! empty( $gradient_color ) ) {+ $fill1 = ! empty( $gradient_color ) ? 'url(#' . esc_attr( $id ) . ')' : '#00000044';+ $fill2 = ! empty( $gradient_color ) ? 'url(#' . esc_attr( $id ) . '-2)' : '#00000088';+ $fill3 = ! empty( $gradient_color ) ? 'url(#' . esc_attr( $id ) . '-3)' : '#000';++ $svg .= '<g>';+ $svg .= '<path d="m1200 40v-40h-1200v40h.39l600 60 600-60z" opacity=".25" fill="' . esc_attr( $fill1 ) . '"/>';+ $svg .= '<path d="m1200 20v-20h-1200v20h.39l600 80 600-80z" opacity=".5" fill="' . esc_attr( $fill2 ) . '"/>';+ $svg .= '<path d="m600 100-600-100h1200z" fill="' . esc_attr( $fill3 ) . '"/>';+ $svg .= '</g>';+ if ( ! empty( $gradient_color ) ) {+ $svg .= $this->render_gradient_svg( $id, $gradient_color, $gradient_angle );+ }+ if ( ! empty( $gradient_color2 ) ) {+ $svg .= $this->render_gradient_svg( $id . '-2', $gradient_color2, $gradient_angle2 );+ }+ if ( ! empty( $gradient_color3 ) ) {+ $svg .= $this->render_gradient_svg( $id . '-3', $gradient_color3, $gradient_angle3 );+ }+ } else {+ $svg .= '<g>';+ $svg .= '<path d="m1200 40v-40h-1200v40h.39l600 60 600-60z" opacity=".25"/>';+ $svg .= '<path d="m1200 20v-20h-1200v20h.39l600 80 600-80z" opacity=".5"/>';+ $svg .= '<path d="m600 100-600-100h1200z"/>';+ $svg .= '</g>';+ }++ $svg .= '</svg>';+ return $svg;+ }++ /**+ * Render waves_o1 SVG.+ *+ * @param string $id Gradient ID.+ * @param bool $invert Invert.+ * @param bool $gradient Use gradient.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @param array $gradient_color2 Gradient color stops 2.+ * @param mixed $gradient_angle2 Gradient angle 2.+ * @param array $gradient_color3 Gradient color stops 3.+ * @param mixed $gradient_angle3 Gradient angle 3.+ * @return string+ */+ private function render_waves_o1_svg( $id, $invert, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 ) {+ if ( $invert ) {+ $d1 = 'm 1082.4844,94.447264 c -62.584,0.1462 -128.54456,-17.780467 -183.78518,-33.386717 l -1.84961,-0.53125 c -34.6,-9.78 -68.29922,-19.86 -104.44922,-25 -58.16,-8.21 -114.93008,-5.79 -171.58008,3.75 -12.607,2.1467 -25.21331,4.619922 -37.82031,7.419922 -70.66,15.64 -144.35922,33.71 -218.19922,30 -35.25,-1.79 -69.38023,-8.629844 -103.49023,-15.589844 C 227.20055,54.149375 193.16,47.079062 158,44.789062 103.82,41.259062 48.269141,49.659141 0.61914062,68.369141 L 0,68.609375 V 0 h 1200 v 63.359375 c -11.15,7.2568 -23.0898,13.220084 -35.5898,17.771484 -25.7282,9.449995 -53.4786,13.249955 -81.9258,13.316405 z';+ $d2 = 'm 1107.9219,89.015624 c -57.8911,1.35234 -118.85487,-17.689921 -172.65237,-37.294921 -9.12,-3.33 -17.99922,-6.681406 -26.69922,-9.941406 -36.21,-13.65 -71.47054,-27.710078 -109.31054,-34.830077 -74.4,-14.0000004 -146.65063,-5.83875 -219.14063,15.531249 -4,1.18 -8,2.365293 -12,3.558593 -70.28,20.88 -143.23961,43.191016 -216.34961,38.291016 C 328.60953,62.770078 305.90086,58.42 283.38086,53 c -49.19,-11.84 -97.53,-28.819453 -148,-33.189453 C 89.352759,15.910547 43.0418,22.600141 0,39.369141 V 0 h 1200 v 64.369141 c -11.22,6.6033 -23.1598,11.893318 -35.5898,15.761718 -18.235,5.7175 -37.1913,8.433985 -56.4883,8.884765 z';+ $d3 = 'M 95.445312,92.011714 C 62.091582,91.343224 29.786641,84.625391 0.61914062,68.369141 L 0,68 V 0 h 1200 v 61.710938 c -48.55,-22.200001 -105.2398,-32.170001 -160.5098,-28 -35.47,2.67 -69.85067,10.89 -104.22067,19 -12.18,2.869999 -24.35031,5.739843 -36.57031,8.339843 -22.82,4.85 -45.80883,8.778438 -69.29883,10.148438 -70.46,4.1 -140.80008,-14.398672 -208.58008,-31.888672 L 607.73047,35.939453 C 594.52347,32.566153 581.31914,29.5867 568.11914,27 510.99914,16 453.67,13.279141 395,22.869141 c -36.72,6 -70.99937,17.841797 -106.10938,29.341797 L 283.38086,54 c -7.187,2.3467 -14.54331,4.712909 -22.07031,7.099609 -51.76875,16.3375 -110.27569,32.026265 -165.865238,30.912105 z';+ } else {+ $d1 = 'm1200 0v46.29c-48.55 22.2-105.24 32.17-160.51 28-35.47-2.67-69.85-10.89-104.22-19-12.18-2.87-24.35-5.74-36.57-8.34-22.82-4.85-45.81-8.78-69.3-10.15-70.46-4.1-140.8 14.4-208.58 31.89l-13.09 3.37c-13.207 3.3733-26.41 6.3533-39.61 8.94-57.12 11-114.45 13.72-173.12 4.13-36.72-6-71-17.84-106.11-29.34l-5.51-1.79c-7.187-2.3467-14.543-4.7133-22.07-7.1-82.83-26.14-182.91-50.62-260.69-7.27l-.62.37v-40z';+ $d2 = 'm1200 0v43.63c-11.22-6.6033-23.16-11.8916-35.59-15.76-72.94-22.87-157.41 2.27-229.14 28.41-9.12 3.33-18 6.68-26.7 9.94-36.21 13.65-71.47 27.71-109.31 34.83-74.4 14-146.65 5.84-219.14-15.53-4-1.18-8-2.3667-12-3.56-70.28-20.88-143.24-43.19-216.35-38.29-23.16 1.56-45.87 5.91-68.39 11.33-49.19 11.84-97.53 28.82-148 33.19-46.0281 3.9-92.3382-2.791-135.38-19.56v-68.63z';+ $d3 = 'm1200 0v44.64c-11.15-7.2568-23.09-13.2186-35.59-17.77-82.33-30.24-185.36-2.63-265.71 20.07l-1.85.53c-34.6 9.78-68.3 19.86-104.45 25-58.16 8.21-114.93 5.79-171.58-3.75-12.607-2.1467-25.213-4.62-37.82-7.42-70.66-15.64-144.36-33.71-218.2-30-35.25 1.79-69.38 8.63-103.49 15.59s-68.15 14.03-103.31 16.32c-54.18 3.53-109.73-4.87-157.38-23.58l-.62-.24v-39.39z';+ }++ return $this->render_triple_layer_svg( $id, '0 0 1200 108', '1200', '108', $d1, $d2, $d3, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );+ }++ /**+ * Render waves_o2 SVG.+ *+ * @param string $id Gradient ID.+ * @param bool $invert Invert.+ * @param bool $gradient Use gradient.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @param array $gradient_color2 Gradient color stops 2.+ * @param mixed $gradient_angle2 Gradient angle 2.+ * @param array $gradient_color3 Gradient color stops 3.+ * @param mixed $gradient_angle3 Gradient angle 3.+ * @return string+ */+ private function render_waves_o2_svg( $id, $invert, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 ) {+ if ( $invert ) {+ $d1 = 'M 992.22461,172.26953 C 962.50049,172.31348 931.25,169.5 900,162 800,138 700,66 600,30 500,-6 400,-6 300,12 200,30 100,66 50,83.999997 L 0,102 V 0 h 1200 v 138 l -50,12 c -34.375,8.25 -92.3823,22.17285 -157.77539,22.26953 z';+ $d2 = 'M 974.21875,133.45508 C 950,132.72666 925,130.39628 900,125.73438 800,107.08688 700,51.14287 600,23.17188 500,-4.79912 400,-4.7985 300,9.1875 200,23.1725 100,51.14291 50,65.12891 L 0,79.11523 V 0 h 1200 v 107.08594 l -50,9.32422 c -37.5,6.99277 -103.125,19.23019 -175.78125,17.04492 z';+ $d3 = 'M 974.21875,107.58789 C 950,107.00066 925,105.12156 900,101.36328 800,86.330177 700,41.23164 600,18.68164 500,-3.86836 400,-3.86875 300,7.40625 200,18.68125 100,41.23186 50,52.50586 L 0,63.7793 V 0 h 1200 v 86.330077 l -50,7.51563 c -37.5,5.63745 -103.125,15.503873 -175.78125,13.742183 z';+ } else {+ $d1 = 'm0 127.22 50 11.275c50 11.274 150 33.824 250 45.099s200 11.275 300-11.275 200-67.649 300-82.6821 200 0 250 7.5166l50 7.5165v-104.67c-400 0-800 0-1200 0z';+ $d2 = 'm0 111.885 50 13.986c50 13.986 150 41.957 250 55.942 100 13.986 200 13.986 300-13.985s200-83.9141 300-102.5616c100-18.6476 200 0 250 9.3237l50 9.3238v-83.9139c-400 0-800 0-1200 0z';+ $d3 = 'm0 89 50 18c50 18 150 54 250 72s200 18 300-18 200-108 300-132 200 0 250 12l50 12v-53c-400 0-800 0-1200 0z';+ }++ return $this->render_triple_layer_svg( $id, '0 0 1200 191', '1200', '191', $d1, $d2, $d3, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );+ }++ /**+ * Render waves_o3 SVG.+ *+ * @param string $id Gradient ID.+ * @param bool $invert Invert.+ * @param bool $gradient Use gradient.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @param array $gradient_color2 Gradient color stops 2.+ * @param mixed $gradient_angle2 Gradient angle 2.+ * @param array $gradient_color3 Gradient color stops 3.+ * @param mixed $gradient_angle3 Gradient angle 3.+ * @return string+ */+ private function render_waves_o3_svg( $id, $invert, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 ) {+ if ( $invert ) {+ $d1 = 'M 1200,104.81054 C 1123.66,65.710547 1037.7292,27 951.19922,20 885.99922,14.76 827.93,32.780234 769,58.490234 c -53.08,23.16 -106.56055,44.030386 -165.56055,35.400391 -43.38,-6.34 -84.60937,-18.820937 -127.60937,-26.460937 C 314.09008,38.679687 149.93,50.999141 0,104.36914 V 0 h 1200 z';+ $d2 = 'm 458.5918,108.25976 c -4.47149,0.106 -8.97922,-0.0129 -13.51172,-0.36914 C 398.98008,104.22062 355.17,77.220703 314.25,58.220703 284.67,44.490703 255.73008,28.569922 224.58008,18.419922 165.00008,-1.00008 99.409453,-1.27078 47.689453,37.949219 27.639453,53.139219 13,73.079453 0,94.189453 V 0 h 1200 v 88.560547 c -12.65,-22.31 -38.2204,-38.350234 -60.6504,-49.240235 -28.09,-13.67 -56.8898,-16.159999 -87.0898,-7.5 -55.62003,15.960001 -109.17042,44.689844 -168.90042,38.839844 -41.76001,-4.05 -79.13993,-25.460781 -116.91993,-43.050781 -37.78,-17.59 -78.6889,-35.069295 -119.1289,-24.279295 -41.31,10.999998 -71.86086,47.609998 -103.63086,72.999998 -24.2375,19.3725 -53.7875,31.187712 -85.08789,31.929682 z';+ $d3 = 'm 1090.2754,93.935547 c -65.567,2.081933 -135.52579,-20.480859 -193.42579,-39.724609 -34.6,-11.5 -68.29922,-23.341797 -104.44922,-29.341797 -71.1,-11.8 -140.13039,-4.919922 -209.40039,13.080078 -70.66,18.38 -144.35922,39.621718 -218.19922,35.261719 -70.47,-4.19 -136.44078,-32.13 -206.80078,-37.5 -54.41,-4.170001 -110.21,5.799999 -158,28 V 0 h 1200 v 57.529297 c -32.625,25.035 -70.3844,35.15709 -109.7246,36.40625 z';+ } else {+ $d1 = 'm0 0v46.29c47.79 22.2 103.59 32.17 158 28 70.36-5.37 136.33-33.31 206.8-37.5 73.84-4.36 147.54 16.88 218.2 35.26 69.27 18 138.3 24.88 209.4 13.08 36.15-6 69.85-17.84 104.45-29.34 92.64-30.79 216.15-70.08 303.15-3.32v-52.47z';+ $d2 = 'm0 0v15.81c13 21.11 27.64 41.05 47.69 56.24 51.72 39.22 117.31 38.95 176.89 19.53 31.15-10.15 60.09-26.07 89.67-39.8 40.92-19 84.73-46 130.83-49.67 36.26-2.85 70.9 9.42 98.6 31.56 31.77 25.39 62.32 62 103.63 73 40.44 10.79 81.35-6.69 119.13-24.28s75.16-39 116.92-43.05c59.73-5.85 113.28 22.88 168.9 38.84 30.2 8.66 59 6.17 87.09-7.5 22.43-10.89 48-26.93 60.65-49.24v-21.44z';+ $d3 = 'm0 0v5.63c149.93 53.37 314.09 65.69 475.83 36.94 43-7.64 84.23-20.12 127.61-26.46 59-8.63 112.48 12.24 165.56 35.4 58.93 25.71 117 43.73 182.2 38.49 86.53-7 172.46-45.71 248.8-84.81v-5.19z';+ }++ return $this->render_triple_layer_svg( $id, '0 0 1200 110', '1200', '110', $d1, $d2, $d3, $gradient, $gradient_color, $gradient_angle, $gradient_color2, $gradient_angle2, $gradient_color3, $gradient_angle3 );+ }++ /**+ * Render zigzag SVG.+ *+ * @param string $id Gradient ID.+ * @param bool $gradient Use gradient.+ * @param array $gradient_color Gradient color stops.+ * @param mixed $gradient_angle Gradient angle.+ * @return string+ */+ private function render_zigzag_svg( $id, $gradient, $gradient_color, $gradient_angle ) {+ // phpcs:ignore Generic.Files.LineLength.TooLong -- SVG path data.+ $d = 'M0 0V0.613924V0.632911V5L3.98 0.632911H4.02L8 5L11.98 0.632911H12.02L16 5L19.98 0.632911H20.02L24 5L27.98 0.632911H28.02L32 5L35.98 0.632911H36.02L40 5L43.98 0.632911H44.02L48 5L51.98 0.632911H52.02L56 5L59.98 0.632911H60.02L64 5L67.98 0.632911H68.02L72 5L75.98 0.632911H76.02L80 5L83.98 0.632911H84.02L88 5L91.98 0.632911H92.02L96 5L99.98 0.632911H100.02L104 5L107.98 0.632911H108.02L112 5L115.98 0.632911H116.02L120 5L123.98 0.632911H124.02L128 5L131.98 0.632911H132.02L136 5L139.98 0.632911H140.02L144 5L147.98 0.632911H148.02L152 5L155.98 0.632911H156.02L160 5L163.98 0.632911H164.02L168 5L171.98 0.632911H172.02L176 5L179.98 0.632911H180.02L184 5L187.98 0.632911H188.02L192 5L195.98 0.632911H196.02L200 5L203.98 0.632911H204.02L208 5L211.98 0.632911H212.02L216 5L219.98 0.632911H220.02L224 5L227.98 0.632911H228.02L232 5L235.98 0.632911H236.02L240 5L243.98 0.632911H244.02L248 5L251.98 0.632911H252.02L256 5L259.98 0.632911H260.02L264 5L267.98 0.632911H268.02L272 5L275.98 0.632911H276.02L280 5L283.98 0.632911H284.02L288 5L291.98 0.632911H292.02L296 5L299.98 0.632911H300.02L304 5L307.98 0.632911H308.02L312 5L315.98 0.632911H316.02L320 5L323.98 0.632911H324.02L328 5L331.98 0.632911H332.02L336 5L339.98 0.632911H340.02L344 5L347.98 0.632911H348.02L352 5L355.98 0.632911H356.02L360 5L363.98 0.632911H364.02L368 5L371.98 0.632911H372.02L376 5L379.98 0.632911H380.02L384 5L387.98 0.632911H388.02L392 5L395.98 0.632911H396.02L400 5L403.98 0.632911H404.02L408 5L411.98 0.632911H412.02L416 5L419.98 0.632911H420.02L424 5L427.98 0.632911H428.02L432 5L435.98 0.632911H436.02L440 5L443.98 0.632911H444.02L448 5L451.98 0.632911H452.02L456 5L459.98 0.632911H460.02L464 5L467.98 0.632911H468.02L472 5L475.98 0.632911H476.02L480 5L483.98 0.632911H484.02L488 5L491.98 0.632911H492.02L496 5L499.98 0.632911H500.02L504 5L507.98 0.632911H508.02L512 5L515.98 0.632911H516.02L520 5L523.98 0.632911H524.02L528 5L531.98 0.632911H532.02L536 5L539.98 0.632911H540.02L544 5L547.98 0.632911H548.02L552 5L555.98 0.632911H556.02L560 5L563.98 0.632911H564.02L568 5L571.98 0.632911H572.02L576 5L579.98 0.632911H580.02L584 5L587.98 0.632911H588.02L592 5L595.98 0.632911H596.02L600 5L603.98 0.632911H604.02L608 5L611.98 0.632911H612.02L616 5L619.98 0.632911H620.02L624 5L627.98 0.632911H628.02L632 5L635.98 0.632911H636.02L640 5L643.98 0.632911H644.02L648 5L651.98 0.632911H652.02L656 5L659.98 0.632911H660.02L664 5L667.98 0.632911H668.02L672 5L675.98 0.632911H676.02L680 5L683.98 0.632911H684.02L688 5L691.98 0.632911H692.02L696 5L699.98 0.632911H700.02L704 5L707.98 0.632911H708.02L712 5L715.98 0.632911H716.02L720 5L723.98 0.632911H724.02L728 5L731.98 0.632911H732.02L736 5L739.98 0.632911H740.02L744 5L747.98 0.632911H748.02L752 5L755.98 0.632911H756.02L760 5L763.98 0.632911H764.02L768 5L771.98 0.632911H772.02L776 5L779.98 0.632911H780.02L784 5L787.98 0.632911H788.02L792 5L795.98 0.632911H796.02L800 5L803.98 0.632911H804.02L808 5L811.98 0.632911H812.02L816 5L819.98 0.632911H820.02L824 5L827.98 0.632911H828.02L832 5L835.98 0.632911H836.02L840 5L843.98 0.632911H844.02L848 5L851.98 0.632911H852.02L856 5L859.98 0.632911H860.02L864 5L867.98 0.632911H868.02L872 5L875.98 0.632911H876.02L880 5L883.98 0.632911H884.02L888 5L891.98 0.632911H892.02L896 5L899.98 0.632911H900.02L904 5L907.98 0.632911H908.02L912 5L915.98 0.632911H916.02L920 5L923.98 0.632911H924.02L928 5L931.98 0.632911H932.02L936 5L939.98 0.632911H940.02L944 5L947.98 0.632911H948.02L952 5L955.98 0.632911H956.02L960 5L963.98 0.632911H964.02L968 5L971.98 0.632911H972.02L976 5L979.98 0.632911H980.02L984 5L987.98 0.632911H988.02L992 5L995.98 0.632911H996.02L1000 5L1003.98 0.632911H1004.02L1008 5L1011.98 0.632911H1012.02L1016 5L1019.98 0.632911H1020.02L1024 5L1027.98 0.632911H1028.02L1032 5L1035.98 0.632911H1036.02L1040 5L1043.98 0.632911H1044.02L1048 5L1051.98 0.632911H1052.02L1056 5L1059.98 0.632911H1060.02L1064 5L1067.98 0.632911H1068.02L1072 5L1075.98 0.632911H1076.02L1080 5L1083.98 0.632911H1084.02L1088 5L1091.98 0.632911H1092.02L1096 5L1099.98 0.632911H1100.02L1104 5L1107.98 0.632911H1108.02L1112 5L1115.98 0.632911H1116.02L1120 5L1123.98 0.632911H1124.02L1128 5L1131.98 0.632911H1132.02L1136 5L1139.98 0.632911H1140.02L1144 5L1147.98 0.632911H1148.02L1152 5L1155.98 0.632911H1156.02L1160 5L1163.98 0.632911H1164.02L1168 5L1171.98 0.632911H1172.02L1176 5L1179.98 0.632911H1180.02L1184 5L1187.98 0.632911H1188.02L1192 5L1195.98 0.632911H1196.02L1200 5V0.632911V0.613924V0H0Z';++ return $this->render_single_path_svg( $id, '0 0 1200 5', '1200', '5', $d, $gradient, $gradient_color, $gradient_angle );+ }++ /**+ * Render shape divider (top or bottom).+ *+ * @param string $location 'top' or 'bottom'.+ * @return string+ */+ private function render_shape_divider( $location ) {+ $attr_key = 'top' === $location ? 'topDivider' : 'bottomDivider';+ $divider = isset( $this->attributes[ $attr_key ] ) ? $this->attributes[ $attr_key ] : array();++ if ( empty( $divider ) ) {+ return '';+ }++ $type = isset( $divider['type'] ) ? $divider['type'] : '';+ $flip = isset( $divider['flip'] ) ? $divider['flip'] : false;+ $front = isset( $divider['front'] ) ? $divider['front'] : false;+ $invert = isset( $divider['invert'] ) ? $divider['invert'] : false;+ $color_mode = isset( $divider['colorMode'] ) ? $divider['colorMode'] : '';++ $classes = array( 'guten-shape-divider', 'guten-shape-divider-' . $location );+ if ( $flip ) {+ $classes[] = 'guten-shape-flip';+ }+ if ( $front ) {+ $classes[] = 'guten-shape-zindex';+ }++ $element_id = $this->get_element_id();+ $divider_id = 'divider-' . $location . '-' . $element_id;++ $svg = '';+ if ( $type && 'none' !== $type ) {+ $svg = $this->render_shape_divider_svg(+ $divider_id,+ $type,+ $invert,+ 'gradient' === $color_mode,+ $divider+ );+ }++ return '<div class="' . esc_attr( implode( ' ', $classes ) ) . '">' . $svg . '</div>';+ }++ /**+ * Render animated shape divider (top or bottom).+ *+ * @param string $location 'top' or 'bottom'.+ * @return string+ */+ private function render_shape_divider_animated( $location ) {+ $attr_key = 'top' === $location ? 'topDividerAnimated' : 'bottomDividerAnimated';+ $divider = isset( $this->attributes[ $attr_key ] ) ? $this->attributes[ $attr_key ] : array();++ $flip = isset( $divider['flip'] ) ? $divider['flip'] : false;+ $front = isset( $divider['front'] ) ? $divider['front'] : false;++ $classes = array( 'guten-shape-divider-animated', 'guten-shape-divider-animated-' . $location );+ if ( $flip ) {+ $classes[] = 'guten-shape-flip';+ }+ if ( $front ) {+ $classes[] = 'guten-shape-zindex';+ }++ return '<div class="' . esc_attr( implode( ' ', $classes ) ) . '"></div>';+ }++ /**+ * Render view in editor+ */+ public function render_gutenberg() {+ return null;+ }++ /**+ * Render view in frontend+ */+ public function render_frontend() {+ if ( ! empty( trim( $this->block_data->inner_html ) ) && apply_filters( 'gutenverse_force_dynamic', false ) ) {+ return $this->content;+ }++ // Snapshot attributes before rendering inner blocks, since this class is a singleton+ // and nested block renders will overwrite $this->attributes.+ $attributes = $this->attributes;++ $element_id = $this->get_element_id();+ $display_classes = $this->set_display_classes();+ $animation_class = $this->set_animation_classes();+ $custom_classes = $this->get_custom_classes();+ $anchor = isset( $attributes['anchor'] ) ? $attributes['anchor'] : '';++ // Extract attributes with defaults.+ $layout = isset( $attributes['layout'] ) ? $attributes['layout'] : 'boxed';+ $gap = isset( $attributes['gap'] ) ? $attributes['gap'] : 'default';+ $align = isset( $attributes['align'] ) ? $attributes['align'] : '';+ $overflow = isset( $attributes['overflow'] ) ? $attributes['overflow'] : '';+ $sticky = isset( $attributes['sticky'] ) ? $attributes['sticky'] : array();+ $sticky_position = isset( $attributes['stickyPosition'] ) ? $attributes['stickyPosition'] : 'top';+ $background_animated = isset( $attributes['backgroundAnimated'] ) ? $attributes['backgroundAnimated'] : array();+ $cursor_effect = isset( $attributes['cursorEffect'] ) ? $attributes['cursorEffect'] : array();+ $background_effect = isset( $attributes['backgroundEffect'] ) ? $attributes['backgroundEffect'] : array();+ $background_overlay = isset( $attributes['backgroundOverlay'] ) ? $attributes['backgroundOverlay'] : array();+ $background_overlay_h = isset( $attributes['backgroundOverlayHover'] ) ? $attributes['backgroundOverlayHover'] : array();+ $background = isset( $attributes['background'] ) ? $attributes['background'] : array();+ $top_divider = isset( $attributes['topDivider'] ) ? $attributes['topDivider'] : array();+ $bottom_divider = isset( $attributes['bottomDivider'] ) ? $attributes['bottomDivider'] : array();+ $top_div_animated = isset( $attributes['topDividerAnimated'] ) ? $attributes['topDividerAnimated'] : array();+ $bottom_div_animated = isset( $attributes['bottomDividerAnimated'] ) ? $attributes['bottomDividerAnimated'] : array();++ // Computed flags.+ $_is_sticky = $this->is_sticky( $sticky );+ $_is_bg_animated = $this->is_animation_active( $background_animated );+ $_is_top_div_animated = ! $this->is_empty_value( $top_div_animated ) && ( ! isset( $top_div_animated['type'] ) || 'none' !== $top_div_animated['type'] );+ $_is_bottom_div_animated = ! $this->is_empty_value( $bottom_div_animated ) && ( ! isset( $bottom_div_animated['type'] ) || 'none' !== $bottom_div_animated['type'] );+ $is_slideshow = isset( $background['slideImage'] ) && is_array( $background['slideImage'] ) && count( $background['slideImage'] ) > 0;+ $is_background_effect = ! empty( $background_effect ) && isset( $background_effect['type'] ) && 'none' !== $background_effect['type'];+ $using_featured_image = ! empty( $background['useFeaturedImage'] ) && ( ! empty( $background['useFeaturedImage']['Desktop'] ) || ! empty( $background['useFeaturedImage']['Tablet'] ) || ! empty( $background['useFeaturedImage']['Mobile'] ) );+ $cursor_effect_show = ! empty( $cursor_effect['show'] );++ $data_id = $this->get_data_id();++ // Build section class name.+ $section_classes = array();+ $section_classes[] = 'wp-block-gutenverse-section';+ $section_classes[] = 'guten-element';+ $section_classes[] = 'guten-section';+ $section_classes[] = $element_id;++ if ( ! empty( trim( $animation_class ) ) ) {+ $section_classes[] = trim( $animation_class );+ }+ if ( ! empty( trim( $display_classes ) ) ) {+ $section_classes[] = trim( $display_classes );+ }+ if ( ! empty( $custom_classes ) ) {+ $section_classes[] = $custom_classes;+ }++ if ( $_is_bg_animated ) {+ $section_classes[] = 'background-animated';+ }+ if ( $layout ) {+ $section_classes[] = 'layout-' . $layout;+ }+ if ( $align ) {+ $section_classes[] = 'align-' . $align;+ }+ if ( $overflow && 'none' !== $overflow ) {+ $section_classes[] = 'overflow-' . $overflow;+ }+ if ( $_is_sticky ) {+ $section_classes[] = 'guten-sticky';+ $section_classes[] = 'sticky-' . $sticky_position;+ }+ if ( $cursor_effect_show ) {+ $section_classes[] = 'guten-cursor-effect';+ }+ if ( $is_background_effect ) {+ $section_classes[] = 'guten-background-effect-active';+ }+ if ( $is_slideshow ) {+ $section_classes[] = 'guten-background-slideshow';+ }+ if ( $using_featured_image ) {+ $section_classes[] = 'guten-using-featured-image';+ }++ $class_name = esc_attr( implode( ' ', array_filter( $section_classes ) ) );++ // Build wrapper class name.+ $wrapper_classes = array( 'section-wrapper' );+ if ( $_is_sticky ) {+ $wrapper_classes[] = 'guten-section-wrapper';+ $wrapper_classes[] = 'section-' . $element_id;+ $wrapper_classes[] = 'sticky-' . $sticky_position;+ }+ $wrapper_class = esc_attr( implode( ' ', $wrapper_classes ) );++ // Container class.+ $container_class = esc_attr( 'guten-container guten-column-gap-' . $gap );++ // Advance animation data attribute.+ $advance_anim_data = $this->render_advance_animation_data();++ // ID attribute.+ $id_attr = ! empty( $anchor ) ? ' id="' . esc_attr( $anchor ) . '"' : '';++ // Build output.+ $output = '<div class="' . $wrapper_class . '" data-id="' . esc_attr( $data_id ) . '">';+ $output .= '<section class="' . $class_name . '"' . $advance_anim_data . $id_attr . '>';++ // FluidCanvasSave - apply filter (returns null by default).+ $fluid_canvas = apply_filters( 'gutenverse_fluid_canvas_script', '', $attributes );+ if ( ! empty( $fluid_canvas ) ) {+ $output .= $fluid_canvas;+ }++ // Guten data div.+ $output .= $this->render_guten_data( $data_id, $_is_sticky, $_is_bg_animated, $_is_top_div_animated, $_is_bottom_div_animated, $is_slideshow );++ // Background animated layer.+ $slide_elements = $this->render_slide_elements();+ if ( $_is_bg_animated ) {+ $output .= '<div class="guten-background-animated"><div class="animated-layer animated-' . esc_attr( $data_id ) . '">';+ if ( $is_slideshow ) {+ $output .= $slide_elements;+ }
AI Analysis
Vulnerability Existed: yes
Unsafe SVG/HTML Output in SVG Rendering Methods [Lines 404-440, 455-475, 495-570, and throughout SVG rendering methods]
Old Code:
```php
$svg = '<svg class="guten-shape-fill" viewBox="' . esc_attr( $viewbox ) . '" preserveAspectRatio="none" fill="none" height="' . esc_attr( $height ) . '" width="' . esc_attr( $width ) . '" xmlns="http://www.w3.org/2000/svg">';
$svg .= '<path d="' . $d . '" fill="' . esc_attr( $fill ) . '"/>';
```
Fixed Code:
```php
$svg = '<svg class="guten-shape-fill" viewBox="' . esc_attr( $viewbox ) . '" preserveAspectRatio="none" fill="none" height="' . esc_attr( $height ) . '" width="' . esc_attr( $width ) . '" xmlns="http://www.w3.org/2000/svg">';
$svg .= '<path d="' . esc_attr( $d ) . '" fill="' . esc_attr( $fill ) . '"/>';
```
---
Vulnerability Existed: yes
Unsafe JSON Encoding Output [Lines 125-140]
Old Code:
```php
$output .= '<div data-var="stickyData' . esc_attr( $data_id ) . '" data-value="' . esc_attr( wp_json_encode( $sticky_data, $json_flags ) ) . '"></div>';
```
Fixed Code:
The code uses `wp_json_encode()` with `esc_attr()` which is correct, but ensure all array values in `$sticky_data` are properly sanitized before encoding. Consider validating the input attributes before use.
---
Vulnerability Existed: yes
Potential XSS via Image URL in Style Attribute [Line 184]
Old Code:
```php
$style_attr = ! empty( $image_url ) ? ' style="background-image: url(' . esc_url( $image_url ) . ')"' : '';
```
Fixed Code:
```php
$style_attr = ! empty( $image_url ) ? ' style="background-image: url(' . esc_url( $image_url, array( 'http', 'https' ) ) . ')"' : '';
```
---
Vulnerability Existed: yes
Insufficient Escaping of SVG Path Data [Multiple locations: Lines 417, 447, 530, 550, 880, etc.]
Old Code:
```php
$svg .= '<path d="' . $d1 . '" opacity=".25" fill="' . esc_attr( $fill1 ) . '"/>';
```
Fixed Code:
```php
$svg .= '<path d="' . esc_attr( $d1 ) . '" opacity=".25" fill="' . esc_attr( $fill1 ) . '"/>';
```
CVE Analysis Results:
CVE-2026-2868: Yes
View CVE Description
The Gutenverse – Ultimate WordPress FSE Blocks Addons & Ecosystem plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'separatorIconSVG' parameter in versions up to, and including, 3.5.3 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
Showing 1 to 9 of 9 results