During _form_validate(), drupal_strlen() and then mb_strlen() get called. Each of these functions currently can only work on strings, not arrays. However, _form_validate() is not smart enough to only send strings to drupal_strlen. When using multiple value form fields, especially taxonomy related form fields, _form_validate() often gets arrays of values. A casual search turned up around a half dozen cases of contributing modules running up against this bug.
If necessary, I can provide logged backtraces of how this happens in 6.22 with TaxiSelect module, for example. However, I will need to sanitize the backtrace before I can post it here, and will do so only on request.
I recommend one of the following changes be made:
1. modify _form_validate() to more intelligently handle arrays, perhaps doing a separate drupal_strlen on each string in the array? (best solution, but I can see some cases where this could have unintended results)
2. have drupal_strlen() detect when it has been passed an array, then send mb_strlen only the first string in the array (least mess solution, but does not 100% guarantee validation as intended)
3. Force all contrib modules to work around this limitation (best case for core and consistent validation, but probably worst case for the community and truly closing this bug)
Comments
Comment #1
asb commentedI'm seeing a similar warning in watchdog log:
This is being logged dozends of times per minute, so it'd be really nice to get rid of it.
Related issues:
Comment #2
pokepasa commentedHi, higherform.
I, bored of seeing the same error while my users edit forms in other language than english, I make a workaround, at least to evade the error in the log. Is this:
Edit the includes/unicode.inc file:
At line 406 you will find the drupal_strlen function, with the mb_strlen failing method.
Now just add this code
function drupal_strlen($text) {
global $multibyte;
if (is_array($text)) {
$text = $text[1];
}
if ($multibyte == UNICODE_MULTIBYTE) {
return mb_strlen($text);
}
else {
// Do not count UTF-8 continuation bytes.
return strlen(preg_replace("/[\x80-\xBF]/", '', $text));
}
}
This checks for an array and get only the first value of the array to avoid the array error. It is not perfect, but in any case the function mb_strlen was failing with the array, so I think that no problems will be expected.
Comment #3
itarato commentedHi Guys,
Can somebody give a sample flow of steps how could the bug be reproduced? I'm trying to get it for 2 days without any success. I installed Taxiselect and played with it couple of hours - it gave me lots of errors but none of them were the mb_string problem.
Thanks!
Comment #4
pokepasa commentedWell, I dont know about Taxiselect, but I can tell you my config:
Just nodes with imagefield, taxonomy and nothing more.
i18 module installed.
Observe that, in english, all worked fine, but when I chose spanish (I have multilanguage config as path only, it is adding /es/ to urls) then the errors appeared, always.
I'm supposing that i18 adds some arrays to have original-translated content (or something similar) and then mb_string error appears.
Comment #5
shaneonabike commented+1
Comment #6
caspercash commented+1
Comment #7
Bill Choy commented+1
If an array is passed you should recursively get the length of all elements. Where the element can be either a string or an array of strings.
PS: I wouldn't just reference $text[1] in case it is an associated array.
Comment #8
Bill Choy commentedComment #9
jcodes.me commentedRelating to #2, I got fixed it this way. Try to override the function rather than editing core files, if you want to use files in your other sites too.
Path:
includes/unicode.incSearch for
function drupal_strlen($text) {Replace that entire function as below:
Note: tested in drupal 7 only