Problem/Motivation

In custom_field module, i pull in the schema from ui-patterns components and if something is using the:
$ref: "ui-patterns://identifier"

As in the case of the bootstrap accordion item component. The pattern that is defined in the schema doesn't work when applied as #pattern attribute on the form element. Drupal returns an error:

Warning: preg_match(): Compilation failed: character code point value in \x{} or \o{} is too large at offset 38 in Drupal\Core\Render\Element\FormElementBase::validatePattern() (line 154 of /var/www/html/web/core/lib/Drupal/Core/Render/Element/FormElementBase.php)

Steps to reproduce

  1. Install custom_field module using applied patch https://www.drupal.org/project/custom_field/issues/3585475
  2. Install ui_suite_bootstrap module
  3. Add a custom field to an entity type, use the "Single directory component" formatter display and try to enter something in the prop id field. A valid string fails validation here. Because this setting is in ajax modal, the element just shows as invalid with error, however enabling the custom_field_sdc sub-module and doing the same component as a page display will trigger the error above on saving the display.

Proposed resolution

Simplify the regex pattern to ensure it still works without error.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

apmsooner created an issue.

pdureau’s picture

The main goal of this proposal is to be compatible with HTML pattern attributes, and it may be necessary :) Because it already works OK with UI Patterns in TextfieldWidget:

    if (isset($this->propDefinition["pattern"])) {
      $form['value']['#pattern_unicode'] = $this->propDefinition["pattern"];
      $description[] = $this->t("Constraint: @pattern", ["@pattern" => $this->propDefinition["pattern"]]);
    }

#pattern_unicode is a UI Patterns specific form property, which is transformed to #pattern compatible schema in UnicodePatternValidatorTrait::pregMatchUnicodePattern().

Maybe Andy (@apmsooner) just need a similar mechanism in custom_field module, without the need of changing the schema on UI Patterns side.

However, let's not discard the proposal too fast. This is the opportunity of simplifying the identifier prop type schema: (?:--|-?[A-Za-z_\x{00A0}-\x{10FFFF}])[A-Za-z0-9-_\x{00A0}-\x{10FFFF}\.]*

With the upcoming #3567610: Adopt Core's stream wrapper, our prop types will not stay "hidden" in plugin attributes anymore, they will be duplicated in schema.json files, shared and copied by themes, copy pasted in SDC definition files... it is a totally new dynamic, and at the end prop types plugins may disappear ;) So it is important to keep the schema understandable any front-developers and sharable with a low risk of mistakes.

Let's check if the current proposal (^(?:--|-?[A-Za-z_])[A-Za-z0-9-_\.]*$):

  • cover the same constraints we need (or nearly the same, let's not be perectionist)
  • don't break anything with component authors using ui-patterns://identifier
  • can be used alongside the previous schema (with JSON schema's anyOf for example) to not break the components explicitly using it (low probability it is happening, but we don't know..)
apmsooner’s picture

Pierre,

Perhaps where I'm a little concerned and/or confused is that I assumed the pattern property in SDC schema would normally imply a javascript pattern but you are using it to do server side validation. The json schema spec says that pattern should comply with ECMA-262 regular expression dialect.

https://json-schema.org/draft/2020-12/json-schema-validation#name-pattern

I realize you pointed to a helper function that can convert the pattern but shouldn't we be complying with the spec in the first place and imply the pattern in SDC should mean it is expected to be form element #pattern compatible by default? I think otherwise this could cause some messy conflict with other modules like mine and Canvas that would assume spec compliance. In summary why I can't really get the test to pass and ensure nothing breaks is:

JSON Schema expects regexes that are valid when passed to JavaScript’s new RegExp(pattern, "u") (Unicode mode). That’s why:

\u{00A0}-\u{10FFFF} is correct.
\x{00A0}-\x{10FFFF} is not (it’s PCRE-only).

pdureau’s picture

Perhaps where I'm a little concerned and/or confused is that I assumed the pattern property in SDC schema would normally imply a javascript pattern but you are using it to do server side validation.

You are right, it seems we are not adding the regex to the HTML pattern attribute anymore so there is no client side validation on TextFieldSource anymore.

It seems it was removed in #3494338: [2.0.0-rc1] Firefox: pattern HTML attribute invalid on USB card component. This is wrong and we must restore it first on our side, and maybe we will encounter a similar error than the one you have in custom_field.

apmsooner’s picture

The interesting thing is I was only able to trigger a logged error when the component was selected from outside the field settings form in my custom_field_sdc sub-module's manage display settings. The error is still their in field settings form, it just doesn't get output for you to see it but the underlying functionality just doesn't validate correctly with PCRE-only regex.

I wonder too with a json schema compliant regex, not sure of the need for prop like this to be derived from ui-patterns schema vs. just being of type 'string'? https://git.drupalcode.org/project/ui_suite_bootstrap/-/blob/5.2.x/compo...

pdureau’s picture

For your information: https://www.drupal.org/node/3537128

HTML5 validation will be disabled in Drupal 12

I don't know if it impacts our discussion or not