Plugin Directory

Changeset 3165151


Ignore:
Timestamp:
10/08/2024 05:25:16 PM (6 months ago)
Author:
Petrichorpost
Message:

Updated plugin to version 1.0.8 with new features and bug fixes.

Location:
svgplus/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • svgplus/trunk/includes/class-svgplus-sanitizer.php

    r3165140 r3165151  
    2121     */
    2222    private static function set_allowed_elements($allow_animations) {
    23         // Define base allowed elements
    2423        self::$allowed_elements = [
     24            // Core SVG Elements
    2525            'svg' => ['xmlns', 'xmlns:xlink', 'width', 'height', 'viewBox', 'version', 'preserveAspectRatio', 'style', 'class', 'id'],
    2626            'g' => ['transform', 'opacity', 'style', 'class', 'id'],
    27             'path' => ['d', 'fill', 'stroke', 'stroke-width', 'transform', 'style', 'class', 'id'],
     27            'defs' => ['class', 'id'],
     28            'symbol' => ['id', 'viewBox', 'preserveAspectRatio', 'class'],
     29            'use' => ['x', 'y', 'xlink:href', 'href', 'transform', 'style', 'class', 'id'],
     30            'image' => ['x', 'y', 'width', 'height', 'xlink:href', 'href', 'preserveAspectRatio', 'transform', 'style', 'class', 'id'],
     31
     32            // Shapes
    2833            'rect' => ['x', 'y', 'width', 'height', 'fill', 'stroke', 'stroke-width', 'rx', 'ry', 'transform', 'style', 'class', 'id'],
    2934            'circle' => ['cx', 'cy', 'r', 'fill', 'stroke', 'stroke-width', 'transform', 'style', 'class', 'id'],
     
    3237            'polyline' => ['points', 'fill', 'stroke', 'stroke-width', 'transform', 'style', 'class', 'id'],
    3338            'polygon' => ['points', 'fill', 'stroke', 'stroke-width', 'transform', 'style', 'class', 'id'],
    34             'text' => ['x', 'y', 'dx', 'dy', 'font-family', 'font-size', 'fill', 'stroke', 'stroke-width', 'transform', 'text-anchor', 'style', 'class', 'id'],
     39            'path' => ['d', 'fill', 'stroke', 'stroke-width', 'transform', 'style', 'class', 'id'],
     40
     41            // Text
     42            'text' => ['x', 'y', 'dx', 'dy', 'font-family', 'font-size', 'font-weight', 'fill', 'stroke', 'stroke-width', 'transform', 'text-anchor', 'style', 'class', 'id'],
    3543            'tspan' => ['x', 'y', 'dx', 'dy', 'style', 'class', 'id'],
    36             'defs' => ['class', 'id'],
    37             'clipPath' => ['id', 'transform', 'class'],
    38             'mask' => ['id', 'x', 'y', 'width', 'height', 'maskUnits', 'maskContentUnits', 'class'],
    39             'linearGradient' => ['id', 'x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform', 'spreadMethod', 'class'],
    40             'radialGradient' => ['id', 'cx', 'cy', 'r', 'fx', 'fy', 'gradientUnits', 'gradientTransform', 'spreadMethod', 'class'],
     44            'textPath' => ['xlink:href', 'startOffset', 'method', 'spacing', 'style', 'class', 'id'],
     45
     46            // Gradient and Paint Servers
     47            'linearGradient' => ['id', 'x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform', 'spreadMethod', 'style', 'class'],
     48            'radialGradient' => ['id', 'cx', 'cy', 'r', 'fx', 'fy', 'gradientUnits', 'gradientTransform', 'spreadMethod', 'style', 'class'],
    4149            'stop' => ['offset', 'stop-color', 'stop-opacity', 'style', 'class', 'id'],
    42             'symbol' => ['id', 'viewBox', 'preserveAspectRatio', 'class'],
    43             'use' => ['x', 'y', 'xlink:href', 'transform', 'style', 'class', 'id'],
    44             'image' => ['x', 'y', 'width', 'height', 'xlink:href', 'href', 'preserveAspectRatio', 'transform', 'style', 'class', 'id'],
    45             'pattern' => ['id', 'width', 'height', 'patternUnits', 'patternTransform', 'viewBox', 'preserveAspectRatio', 'xlink:href', 'class'],
    46             'style' => ['type', 'media', 'title'],
     50            'pattern' => ['id', 'width', 'height', 'patternUnits', 'patternTransform', 'viewBox', 'preserveAspectRatio', 'xlink:href', 'style', 'class'],
     51
     52            // Clipping and Masking
     53            'clipPath' => ['id', 'clipPathUnits', 'transform', 'style', 'class'],
     54            'mask' => ['id', 'x', 'y', 'width', 'height', 'maskUnits', 'maskContentUnits', 'style', 'class'],
     55
     56            // Filters and Effects
     57            'filter' => ['id', 'filterUnits', 'x', 'y', 'width', 'height', 'primitiveUnits', 'class'],
     58            'feBlend' => ['in', 'in2', 'mode', 'result', 'class'],
     59            'feColorMatrix' => ['in', 'type', 'values', 'result', 'class'],
     60            'feComponentTransfer' => ['in', 'result', 'class'],
     61            'feComposite' => ['in', 'in2', 'operator', 'k1', 'k2', 'k3', 'k4', 'result', 'class'],
     62            'feConvolveMatrix' => ['in', 'order', 'kernelMatrix', 'divisor', 'bias', 'targetX', 'targetY', 'edgeMode', 'kernelUnitLength', 'preserveAlpha', 'result', 'class'],
     63            'feDiffuseLighting' => ['in', 'surfaceScale', 'diffuseConstant', 'kernelUnitLength', 'result', 'class'],
     64            'feDisplacementMap' => ['in', 'in2', 'scale', 'xChannelSelector', 'yChannelSelector', 'result', 'class'],
     65            'feDistantLight' => ['azimuth', 'elevation', 'class'],
     66            'feDropShadow' => ['dx', 'dy', 'stdDeviation', 'flood-color', 'flood-opacity', 'result', 'class'],
     67            'feFlood' => ['flood-color', 'flood-opacity', 'result', 'class'],
     68            'feFuncA' => ['type', 'tableValues', 'slope', 'intercept', 'amplitude', 'exponent', 'offset', 'class'],
     69            'feFuncB' => ['type', 'tableValues', 'slope', 'intercept', 'amplitude', 'exponent', 'offset', 'class'],
     70            'feFuncG' => ['type', 'tableValues', 'slope', 'intercept', 'amplitude', 'exponent', 'offset', 'class'],
     71            'feFuncR' => ['type', 'tableValues', 'slope', 'intercept', 'amplitude', 'exponent', 'offset', 'class'],
     72            'feGaussianBlur' => ['in', 'stdDeviation', 'edgeMode', 'result', 'class'],
     73            'feImage' => ['xlink:href', 'preserveAspectRatio', 'crossorigin', 'result', 'class'],
     74            'feMerge' => ['result', 'class'],
     75            'feMergeNode' => ['in', 'class'],
     76            'feMorphology' => ['in', 'operator', 'radius', 'result', 'class'],
     77            'feOffset' => ['in', 'dx', 'dy', 'result', 'class'],
     78            'fePointLight' => ['x', 'y', 'z', 'class'],
     79            'feSpecularLighting' => ['in', 'surfaceScale', 'specularConstant', 'specularExponent', 'kernelUnitLength', 'result', 'class'],
     80            'feSpotLight' => ['x', 'y', 'z', 'pointsAtX', 'pointsAtY', 'pointsAtZ', 'specularExponent', 'limitingConeAngle', 'class'],
     81            'feTile' => ['in', 'result', 'class'],
     82            'feTurbulence' => ['baseFrequency', 'numOctaves', 'seed', 'stitchTiles', 'type', 'result', 'class'],
     83
     84            // Metadata Elements
    4785            'metadata' => [],
    4886            'desc' => [],
    4987            'title' => [],
    50             // Add more elements as needed
     88
     89            // Style Element
     90            'style' => ['type', 'media', 'title'],
    5191        ];
    5292
    5393        if ($allow_animations) {
    54             // MODIFIED: Added animation elements and attributes when animations are allowed
    5594            $animation_elements = [
    5695                'animate' => ['attributeName', 'from', 'to', 'dur', 'repeatCount', 'begin', 'end', 'fill', 'values', 'keyTimes', 'keySplines', 'calcMode', 'keyPoints', 'restart', 'repeatDur'],
     
    65104            self::$allowed_elements = array_merge(self::$allowed_elements, $animation_elements);
    66105
    67             // Also, allow 'style' attribute
     106            // Ensure 'style' attribute is allowed
    68107            foreach (self::$allowed_elements as $element => $attributes) {
    69108                if (!in_array('style', $attributes)) {
     
    81120     */
    82121    public static function sanitize_svg($svg_content) {
    83         // MODIFIED: Retrieve 'allow_animations' setting and set allowed elements accordingly
     122        // Retrieve 'allow_animations' setting and set allowed elements accordingly
    84123        $settings = get_option('svgplus_settings');
    85124        $allow_animations = isset($settings['allow_animations']) ? $settings['allow_animations'] : 0;
     
    164203                }
    165204
     205                // Conditionally allow 'style' attributes based on 'allow_animations' setting
    166206                if ($attr_name_lower === 'style') {
    167207                    if (!$allow_animations) {
     
    176216                } else {
    177217                    // Optionally, sanitize attribute values here
    178                     // For example, ensure that URLs are safe
    179218                    $attr_value = $node->getAttribute($attr_name);
    180219                    $sanitized_value = self::sanitize_attribute($attr_name_lower, $attr_value);
     
    216255            case 'fill':
    217256            case 'stroke':
     257            case 'stop-color':
     258            case 'flood-color':
     259            case 'lighting-color':
    218260                // Allow color values (e.g., #fff, rgb(255,255,255))
    219                 // Further validation can be added here
    220                 return htmlspecialchars($attr_value, ENT_QUOTES, 'UTF-8');
    221             // Add more cases as needed
     261                return htmlspecialchars($attr_value, ENT_QUOTES, 'UTF-8');
     262            case 'd':
     263            case 'points':
     264            case 'path':
     265            case 'keyPoints':
     266                // Sanitize path data
     267                return preg_replace('/[^0-9\.\-\s,mlzhvcsqtaMLZHVCSQTA]/', '', $attr_value);
     268            case 'values':
     269            case 'from':
     270            case 'to':
     271            case 'by':
     272            case 'keyTimes':
     273            case 'keySplines':
     274                // Allow numeric sequences and functions
     275                return htmlspecialchars($attr_value, ENT_QUOTES, 'UTF-8');
     276            case 'dur':
     277            case 'begin':
     278            case 'end':
     279            case 'repeatCount':
     280            case 'repeatDur':
     281            case 'calcMode':
     282            case 'additive':
     283            case 'accumulate':
     284            case 'attributeName':
     285            case 'attributeType':
     286            case 'type':
     287            case 'restart':
     288            case 'fill':
     289            case 'rotate':
     290            case 'origin':
     291                // Allow predefined values
     292                return htmlspecialchars($attr_value, ENT_QUOTES, 'UTF-8');
    222293            default:
    223294                return htmlspecialchars($attr_value, ENT_QUOTES, 'UTF-8');
  • svgplus/trunk/readme.txt

    r3165140 r3165151  
    1 == SVGPlus ===
     1=== SVGPlus ===
    22Contributors: Rizonepress
    33Tags: svg, vector graphics, media upload, shortcode, sanitization
    44Requires at least: 5.0
    55Tested up to: 6.6
    6 Stable tag: 1.0.7
     6Stable tag: 1.0.8
    77License: GPLv2 or later
    88License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    4444   - **Via Shortcodes:** Use the `[svgplus id="123"]` shortcode within Elementor’s Shortcode widget to embed SVGs with additional customization options.
    4545
    46 
    4746## Usage
    4847
     
    6059
    61603. **Customize Shortcode (Optional):** Add additional parameters such as custom classes, alt text, and lazy loading:
    62    ```[svgplus id="123" class="custom-svg-class" alt="Description of SVG" lazy="true"]```
     61   ```[svgplus id="123" class="custom-svg-class" alt="Description of SVG" lazy="true"]
     62
    6363
    6464### Configuring Plugin Settings
     
    8383
    8484## Changelog
     85
     86= 1.0.8 =
     87
     88* Comprehensive SVG Element Support: Expanded the list of allowed SVG elements and attributes in the sanitizer to include a complete set of SVG elements, including all filter elements and animation elements. This ensures compatibility with a wider range of SVG files and features.
     89* Enhanced Animation Support: Completed the inclusion of all animation elements and their attributes, allowing for full support of SVG animations when enabled in the settings.
     90* Improved Sanitization Logic: Updated the SVG sanitizer to support advanced SVG features like filters and animations while maintaining strict security measures. The sanitizer now properly handles a more extensive range of elements and attributes.
     91* Security Enhancements: Ensured that the expanded support does not compromise security by maintaining robust sanitization and validation of SVG content.
    8592
    8693= 1.0.7 =
  • svgplus/trunk/svgplus.php

    r3165140 r3165151  
    44 * Plugin URI: https://rizonepress.com
    55 * Description: Securely upload and display SVG files with built-in sanitization and enhanced compatibility with Elementor.
    6  * Version: 1.0.6
     6 * Version: 1.0.8
    77 * Author: <a href="https://rizonepress.com" target="_blank">Rizonepress.com</a>
    88 * Text Domain: svgplus
     
    1717
    1818// Define plugin constants
    19 define('SVGPLUS_VERSION', '1.0.6');
     19define('SVGPLUS_VERSION', '1.0.8');
    2020define('SVGPLUS_PATH', plugin_dir_path(__FILE__));
    2121define('SVGPLUS_URL', plugin_dir_url(__FILE__));
Note: See TracChangeset for help on using the changeset viewer.