xnumber leads to PHP fatal errors in unrelated modules

Created on 7 September 2023, about 1 year ago
Updated 13 September 2023, about 1 year ago

For example search_api_clir creates a standard number form element:
https://git.drupalcode.org/project/search_api_clir/-/blob/2abc3de46aa653...

    $form['third_party_settings']['search_api_clir']['cron']['limit'] = [
      '#type' => 'number',
      '#min' => 0,
      '#title' => t('Limit'),
      '#description' => t('Number of translations to be requested per cron run. Setting it to "0" will disable the cron job.'),
      '#default_value' => $settings['cron']['limit'],
    ];

By simply installing xnumber it hijacks the validation of form elements and causes a fatal error:

TypeError: bcscale(): Argument #1 ($scale) must be of type ?int, float given in bcscale() (line 39 of modules/contrib/xnumber/src/Utility/Xnumber.php).

Drupal\xnumber\Utility\Xnumber::validStep('0.5', 0.1, 0) (Line: 56)
Drupal\xnumber\Render\Element\Xnumber::validateNumber(Array, Object, Array)
call_user_func_array(Array, Array) (Line: 282)
Drupal\Core\Form\FormValidator->doValidateForm(Array, Object) (Line: 238)
Drupal\Core\Form\FormValidator->doValidateForm(Array, Object) (Line: 238)
Drupal\Core\Form\FormValidator->doValidateForm(Array, Object) (Line: 238)
Drupal\Core\Form\FormValidator->doValidateForm(Array, Object) (Line: 238)
Drupal\Core\Form\FormValidator->doValidateForm(Array, Object) (Line: 238)
Drupal\Core\Form\FormValidator->doValidateForm(Array, Object, 'search_api_index_edit_form') (Line: 118)
Drupal\Core\Form\FormValidator->validateForm('search_api_index_edit_form', Array, Object) (Line: 593)
Drupal\Core\Form\FormBuilder->processForm('search_api_index_edit_form', Array, Object) (Line: 325)
🐛 Bug report
Status

Fixed

Version

2.0

Component

Code

Created by

🇩🇪Germany mkalkbrenner 🇩🇪

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

Comments & Activities

  • Issue created by @mkalkbrenner
  • 🇩🇪Germany mkalkbrenner 🇩🇪

    I just checked the schema of search_api_clir. It is correct:

            limit:
              type: integer
              label: 'Limit'
    
  • 🇩🇪Germany mkalkbrenner 🇩🇪

    I did some more debugging and it turned out that the field in question isn't limit but slop which belongs to search_api_solr:

    slop:
        type: float
        label: 'When using the regex fragmenter (hl.fragmenter=regex), this parameter defines the factor by which the fragmenter can stray from the ideal fragment size (given by hl.fragsize) to accommodate a regular expression.'
    
        $form['third_party_settings']['search_api_solr']['highlighter']['regex']['slop'] = [
          '#type' => 'number',
          '#step' => .1,
          '#min' => 0,
          '#title' => t('regex.slop'),
          '#description' => t('When using the regex fragmenter, this parameter defines the factor by which the fragmenter can stray from the ideal fragment size (given by fragsize) to accommodate a regular expression. For instance, a slop of 0.2 with fragsize=100 should yield fragments between 80 and 120 characters in length. It is usually good to provide a slightly smaller fragsize value when using the regex fragmenter.'),
          '#default_value' => $settings['highlighter']['regex']['slop'],
        ];
    

    The issue seems to be caused by the recent changes to XNumber::getDecimalDigits() which gets called with float 0.5 in this case:
    https://git.drupalcode.org/project/xnumber/-/commit/b3c60cfe763bcd65e631...

  • Assigned to drugan
  • 🇪🇪Estonia drugan

    Thanks for reporting.

    The reason is that xnumber whenever possible relies on string numbers which actually you get while using a number form widget in the UI.

    I've fixed it and now trying to add more tests for saving non-string numbers programmatically on entity field.

  • @drugan opened merge request.
  • Status changed to Needs review about 1 year ago
  • 🇪🇪Estonia drugan

    @mkalkbrenner

    I created custom valid step and min and max constraint validators. So now saving xnumber value programmatically works the same as doing it from the UI.

    Also, I added to the XnumberFieldTest a few lines to save an integer or float (non-string) value on entity xnumber field.

    Please check it in your environment and if it's okay I will create 2.0.0-beta1 release.

  • 🇪🇪Estonia drugan

    Adjusted the runRandomNumberDecimalFieldTest() method to newly added constraints.

    This is for xdecimal filed stress testing using random generated value, min and max.

    I think it might be overhead to run this method each time in automatic testing but for debugging purposes you can change "run" prefix for "test" and see what happens.

    • drugan committed 5e67aeec on 2.0.x
      Issue #3385921 by mkalkbrenner, drugan: xnumber leads to PHP fatal...
  • Issue was unassigned.
  • Status changed to Fixed about 1 year ago
  • 🇪🇪Estonia drugan

    Okay, now the module has a great test coverage so there shouldn't be bugs anymore.

    Closing it.

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024