Field UI input breaks content type

Created on 25 October 2024, 3 months ago

Problem/Motivation

Too large initial numeric value in Plain text / Text (plain) -type field configuration breaks the content type.
It seems field storage is not created due to exceeding allowed maximum character for db.
Value is not checked well enough in the process.

Modifying existing content type will only result on

This happens with ddev and Drupal 11.x and MariaDB 10.6.

I was not able to reproduce this in 11.0.5 on my MacBook using:

composer create-project drupal/recommended-project drupal 
cd drupal && php -d memory_limit=256M web/core/scripts/drupal quick-start demo_umami

Steps to reproduce

  1. Install Drupal 11.x running on ddev using Umami demo profile
  2. Edit article content type and add a field
  3. Select "Plain text" and "Text (plain)"
  4. Set "Maximum length" to 25500
  5. Click "Save settings" (form focuses too high a maximum length value)
  6. Do not change anything but re-click "Save settings" and see a WSOD
  7. Navigate to /admin/structure/types and see an error message with SQL
  8. On "Article" click "Manage fields" and see WSOD

This was detected during Drupal Core UX weekly on 25.10.2024 and the meeting recording will show the steps to reproduce (with a site set up in Ngrok).

Proposed resolution

Always validate maximum length before taking action.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

๐Ÿ› Bug report
Status

Active

Version

11.0 ๐Ÿ”ฅ

Component

field system

Created by

๐Ÿ‡ซ๐Ÿ‡ฎFinland simohell

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

Comments & Activities

  • Issue created by @simohell
  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland simohell
  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland simohell
  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland simohell
  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland simohell
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States dan612 Portland, Maine

    I believe this issue can be recreated with any Text (plain) input field, regardless of profile/installation method. After some digging around, I think the problem lies in the validation surrounding the StringItem field type.

    We have a subform being created for max_length but there is no restriction on the highest allowed value for that input. Could we simply provide a #max on the subform element? For instance:

      /**
       * {@inheritdoc}
       */
      public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) {
        $element = [];
    
        $element['max_length'] = [
          '#type' => 'number',
          '#title' => $this->t('Maximum length'),
          '#default_value' => $this->getSetting('max_length'),
          '#required' => TRUE,
          '#description' => $this->t('The maximum length of the field in characters.'),
          '#min' => 1,
          '#max' => 255, // adding this line
          '#disabled' => $has_data,
        ];
    
        return $element;
      }
    

    This leads me to another question...what is the correct max to set here? My inclination is to set a cap of 255, however, I don't think such a restriction exists for the varchar data type. Looking at the MySQL reference manual:

    Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 65,535. The effective maximum length of a VARCHAR is subject to the maximum row size (65,535 bytes, which is shared among all columns) and the character set used. See Section 10.4.7, โ€œLimits on Table Column Count and Row Sizeโ€.

    Now, this changes based on the character set in use. In the example screenshots we can see:

    Column length too big for 'field_test_value' (max=16383)

    The 16,383 comes from the fact that the database is using utfmb4 character encoding which requires 4 bytes per character (65,535 / 4 = 16,383.75 - can't support three-quarters of a character so drop the .75).

    If I set this locally to 16,383 I am still met with the error. The highest value I can input for a max appears to be 16,339. If I set it to more than that I get an error. Why this value? Not sure...seems too arbitrary.

    Additionally, it looks like the storage can specify if ASCII or not - if these characters were limited to ASCII then the max would be much greater as each character only requires 1 byte instead of 4. So if I change this to TRUE, I can then enter a value up to 65,358.

    Right now the questions I have outnumber the solutions ๐Ÿ˜

    1. Where is the Ajax validation coming from on the subform input?
    2. Why is the Ajax validation bypassed on second save?
    3. What is an appropriate max value to set?

    This should also be something that is testable in the StringItemTest...once we know what to set it at ๐Ÿ™ƒ.

Production build 0.71.5 2024