Using Blazy as filter in CKEditor text format causes images with spaces in name to break

Created on 15 July 2020, almost 4 years ago
Updated 29 September 2023, 9 months ago

I've come across an issue when using Blazy as a filter on a CKEditor text format, where images with spaces in the file name get altered and break. Images without spaces in filename are fine. I've tested this without any other filters applied, so it's not just a matter of changing the order.

Steps to recreate:

  • Enable Blazy obviously
  • Enable Blazy as a filter on one of the CKEditor text formats eg. 'Full Html'. /admin/config/content/formats/manage/full_html
  • Create some content using CKEditor and add an image that has a space in the name: eg. 'picture one.jpg'.
  • You will see the image showing up ok in the CKEditor WYSIWYG, but when you save and visit the 'live' page the image won't show up and the path to the image will have changed from:
    /sites/default/files/picture%20one.jpg -> /sites/default/files/picture%2520one.jpg
💬 Support request
Status

Closed: cannot reproduce

Version

2.1

Component

Miscellaneous

Created by

🇬🇧United Kingdom justinchev

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇷🇴Romania martonlaci

    Hello,
    I met a very similar issue. A bare clean test server: Ubuntu 18.04.6 LTS, PHP Version 8.1.18,
    Drupal 9.5.11, Blazy 8.x-2.18, IMCE 3.0.9 all installed via composer.
    Enabled Blazy as a filter on a CKEditor text format.
    Create a new basic page node. Added to the body two jpeg image files, one without space in name the other with space (testimage1.jpg and ‘test image2.jpg’), uploaded them with IMCE file browser in public://images/ folder.
    After saving the node, the image with space in name is not shown. In edit mode is there and can be edited. :)
    I investigated a little bit. Here is my findings.
    The Blazy filter processes the html entered in CKEditor 5, during that processes each img element.
    At some point reaches in the modules/contrib/blazy/src/Plugin/Filter/BlazyFilter.php
    the function withDomElement. Which trying to filter out invalid images, according to remarks in code only the missing local URI is the target.

        // Marks invalid, unknown, missing IMG or IFRAME for removal.
        // Be sure to not affect external images, only strip missing local URI.
        $uri = $blazies->get('image.uri');
    
        $missing = FALSE;
        if ($uri && !BlazyFile::isExternal($uri)) {
          $missing = BlazyFile::isValidUri($uri) && (!is_file($uri));
        }
        if (empty($uri) || $missing) {
          $media->setAttribute('class', 'blazy-removed');
          return [];
        }
    
        // Provides the relevant elements based on the configuration.
        return $this->toElement($blazies, $build);

    I traced here the image URIs returned by $blazies→get('image.uri'); and find it out that the
    "/sites/default/files/images/testimage1.jpg" is not filtered out but the "/sites/default/files/images/test%20image2.jpg" yes!
    The is_file($uri) function returned value was only the difference. It seems that the is_file function does not accept the %20 instead of space!
    In my opinion at this level the uri should not contain any %20 instead of space.
    At first glance I corrected the test as:

        if ($uri && !BlazyFile::isExternal($uri)) {
          $missing = BlazyFile::isValidUri($uri) && (!is_file(str_replace('%20', ' ', $uri)));
        }
    

    But in console a lot of 404 messages popped out
    GET http://d9test.loc/sites/default/files/images/test%20image2.jpg
    Status 404 Not Found

    After a litle bit more searching I added the
    $normal_path = str_replace('%20', ' ', $normal_path);
    line to buildUri function in modules/contrib/blazy/src/Media/BlazyFile.php

      public static function buildUri($url): ?string {
        if (!self::isExternal($url)
          && $normal_path = UrlHelper::parse($url)['path']) {
          // If the request has a base path, remove it from the beginning of the
          // normal path as it should not be included in the URI.
          $base_path = \Drupal::request()->getBasePath();
          if ($base_path && mb_strpos($normal_path, $base_path) === 0) {
            $normal_path = str_replace($base_path, '', $normal_path);
          }
    
          $public_path = Settings::get('file_public_path', 'sites/default/files');
    
          $normal_path = str_replace('%20', ' ', $normal_path);
    
          // Only concerns for the correct URI, not image URL which is already being
          // displayed via SRC attribute. Don't bother language prefixes for IMG.
          if ($public_path && mb_strpos($normal_path, $public_path) !== FALSE) {
            $rel_path = str_replace($public_path, '', $normal_path);
            return self::normalizeUri($rel_path);
          }
        }
        return NULL;
      }
    

    This line resolved my problem with disappearing images with space in file name with Blazy filter enabled in CKEditor 5.
    I’m not sure if it is the correct way to resolve the issue, but may help :)
    Best regards

Production build 0.69.0 2024