Uploaded image for project: 'eZ Publish / Platform'
  1. eZ Publish / Platform
  2. EZP-27876

TextLine Content Field Type Length Validation checks the number of bytes rather than the number of characters

    XMLWordPrintable

    Details

      Description

      When using TextLine Field Typewith set a maximum number of characters, it is actually checking a number of bytes instead of a number of characters. This means that strings with multi-byte characters can in some cases not be validated correctly. For example string "Tęst" will not pass the validation when the maximum characters allowed for that field is 4.
      This issue exists in eZ Platform UI and also in Public API for both eZ Platform and eZ Publish. It doesn't exist in Legacy Admin.
      This issue is caused by using strlen() function instead of mb_strlen (for example here: https://github.com/ezsystems/ezpublish-kernel/blob/master/eZ/Publish/Core/FieldType/TextLine/Type.php#L108). TextLine Field Type is possibly not the only one affected. Also, possibly other functions (like strpos or strstr) should be changed to their multi-byte safe counterparts to avoid other similar errors.

      Steps to reproduce for eZ Platform

      1. Create new eZ Platform installation.
      2. In Platform UI, navigate to "Admin Panel"/"Content types"/"Content" Content Type Group.
      3. There, create a new Content Type with any name and identifier.
      4. Add one Content Field Type to the freshly created Content Type of type TextLine (ezstring) and set its Maximum length to 4 and name it "Title".
      5. Navigate to "Content"/"Content structure". In "eZ Platform" Folder, create a new Content Object of the Type you have created in previous steps. In the "Title" field, enter "Tęst" or similar string with 4 characters and at least one multi-byte character.
      6. Click "Save" button. You will be presented with the error "An error occurred while publishing the draft".

      Steps to reproduce for eZ Publish

      1. Create new eZ Publish installation.
      2. In Legacy Admin, navigate to "Setup"/"Classes"/"Content" Class Group.
      3. There, create a new Class with any name and identifier.
      4. Add one Attribute to the freshly created Class of type Text line (ezstring) and set its Maximum length to 4 and name it "Title".
      5. Navigate to "Content structure". In "Home" Landing Page, create a new Content of the Class you have created in previous steps. In the "Title" field, enter "Tęst" or similar string with 4 characters and at least one multi-byte character.
      6. Click "Send for publishing". The Content will be successfully created.
      7. Now, in your project, create a new Symfony Command TestCommand.php with the following code (change $contentId from 66 to your created object's Object ID):
        <?php
        
        namespace AppBundle\Command;
        
        use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
        use Symfony\Component\Console\Input\InputInterface;
        use Symfony\Component\Console\Output\OutputInterface;
        
        class TestCommand extends ContainerAwareCommand
        {
            protected function configure()
            {
                $this
                    ->setName('app:test_command');
            }
        
            protected function execute(InputInterface $input, OutputInterface $output)
            {
                /** @var $repository \eZ\Publish\API\Repository\Repository */
                $repository = $this->getContainer()->get('ezpublish.api.repository');
                $contentService = $repository->getContentService();
                $repository->setCurrentUser($repository->getUserService()->loadUser(14));
                $contentId = 66;
        
                try {
                    // create a content draft from the current published version
                    $contentInfo = $contentService->loadContentInfo($contentId);
                    $contentDraft = $contentService->createContentDraft($contentInfo);
                    // instantiate a content update struct and set the new fields
                    $contentUpdateStruct = $contentService->newContentUpdateStruct();
                    $contentUpdateStruct->initialLanguageCode = 'eng-GB'; // set language for new version
                    // update and publish draft
                    $contentDraft = $contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
                    $content = $contentService->publishVersion($contentDraft->versionInfo);
                    print_r($content);
                } catch (\eZ\Publish\API\Repository\Exceptions\NotFoundException $e) {
                    $output->writeln($e->getMessage());
                } catch (\eZ\Publish\API\Repository\Exceptions\ContentFieldValidationException $e) {
                    $output->writeln($e->getMessage());
                } catch (\eZ\Publish\API\Repository\Exceptions\ContentValidationException $e) {
                    $output->writeln($e->getMessage());
                }
            }
        }
        
      8. Execute the command by running the following in your console:
        php ezpublish/console app:test_command
        

        You will be presented with the error "Content fields did not validate".

        Attachments

          Activity

            People

            Assignee:
            Unassigned
            Reporter:
            jacek.foremski-obsolete@ez.no Jacek Foremski (Inactive)
            Votes:
            1 Vote for this issue
            Watchers:
            5 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: