This is a relatively easy problem to grasp, even though it's a bit strange to explain.
In element_children() we have code like the following:
foreach ($elements as $key => $value) {
if ($key[0] !== '#') {
...
}
}
Now this can cause a problem if $key is an empty string, which is common when you want to have something like "Select..." as the first option, which will trigger the "Required" error if the user doesn't choose an option. In other words, a form like this will cause an error:
$form['radios'] = array(
'#type' => 'radios',
'#options' => array(
'' => t('Select...'),
'one' => t('Option one'),
),
);
This throws the following PHP warning:
Error message
Notice: Uninitialized string offset: 0 in element_children() (line 5284 of /Users/nate/Sites/drupal7/includes/common.inc).
The simple fix here is we just check that $key has at least one character before trying to check the first character.
Comment | File | Size | Author |
---|---|---|---|
#25 | empty_radio_option_734234-23.patch | 2.64 KB | floretan |
#23 | 734234-empty-radio-option_4.patch | 4.7 KB | ekes |
#18 | empty_radio_option_4.patch | 655 bytes | Melissamcewen |
#5 | empty_radio_option_3.patch | 659 bytes | moonray |
#4 | empty_radio_option_2.patch | 659 bytes | moonray |
Comments
Comment #2
moonray CreditAttribution: moonray commentedRerolled the patch. Tested it to work.
Comment #3
JacineSubscribe. Need this for Skinr :(
Comment #4
moonray CreditAttribution: moonray commentedRe-re-rolling. Hoping the test bot will like it.
Comment #5
moonray CreditAttribution: moonray commentedOK, lets try that again with a patch that won't break drupal (oops).
Comment #6
sociotech CreditAttribution: sociotech commentedThird time's a charm! No more errors. Thumbs up and RTBC.
Comment #7
JacineSame here. Marking RTBC.
Comment #8
quicksketchThanks moonray! I should've rerolled this after it failed to apply. :-(
Moonray's #5 is identical to my original patch, just it has the file path correct for common.inc. As such I know that it works and prevents the PHP warning correctly. RTBC + 1.
Comment #9
webchickSorry, but we need tests for tweaky esoteric bugs like this.
Comment #10
quicksketchReally? This is a PHP programming mistake. Clearly all strings aren't always longer than 1 character. It's equivalent to an isset($variable) versus an implied $variable.
Comment #11
moonray CreditAttribution: moonray commentedI second what quicksketch said in #10. There's no way to really write a test for a programming mistake like this.
Comment #12
JacineOk, let's try again.
Comment #13
Melissamcewen CreditAttribution: Melissamcewen commentedThe patch is working for me. Thanks!
Comment #14
sociotech CreditAttribution: sociotech commentedPatch applied cleanly, resolved uninitialized string offset errors when using Skinr. RTBC +1
Comment #15
chx CreditAttribution: chx commentedABSOLUTELY NOT!
if ($key === '' || $key[0] !== '#') {
is the correct fix. Empty string is a perfect child it's not a property.Comment #16
quicksketchDoh. Chx is totally right (and webchick too), since the fact is that this patch is the opposite of the correct thing.
Comment #17
quicksketchComment #18
Melissamcewen CreditAttribution: Melissamcewen commentedHere is a patch based on chx's wisdom
Comment #19
casey CreditAttribution: casey commentedper #15
Comment #20
webchickHit this with Flag: #874292: Notice: Uninitialized string offset: 0 in element_children() Which I assume is why Nate wanted this fixed. ;)
Anyone up for writing that test? The code is practically written for you in the OP. We just need a select/radios element with a "" option in one of the forms in the form test. Just viewing the form's enough to trigger this issue.
Comment #21
ekes CreditAttribution: ekes commentedLooking at test; and it only makes sense to test radio fapi display / validation generally - as is done for checkbox. Related issues spotted so far:-
And for present 'desired' behaviour. #621366: Enforce comformance to W3C recommendations on radio buttons? is not implemented.
However it's probably easiest to do this in stages; so small test to cover this first, and notes.
Comment #22
ekes CreditAttribution: ekes commentedOh wow.. posted that the wrong issue :) Well not the one I started working on.
But it's good to have all of them collected together
Comment #23
ekes CreditAttribution: ekes commentedPatch from #18 with added simpletests starting on #21
Comment #24
ekes CreditAttribution: ekes commentedComment #25
floretan CreditAttribution: floretan commented@ekes has been faster than me, but I'm not sure we need so much details in the test. We already have the "Form element validation" tests that test a bunch of stuff with different element types and options. Simply adding an option with an empty key throws a warning, which is solved by this patch. Note that only elements of type "radios" throw errors, but I'm also adding an option with an empty key to the select tests for completeness.
Comment #26
salvis$key can also be a numeric index.
I think the proper condition is
What about NULL? Would be weird, but is it illegal? Test for empty()? That would also cover $key===''.
Comment #27
salvisI'm sorry for having derailed this. I thought I had a case of notices tracked back to this code and integer $keys, but now I cannot reproduce it anymore.
So, please ignore my #26 above.
The fix is fine, but I can't say how much testing is needed.
Comment #28
webchickYep, #25 looks like exactly what I had in mind.
Committed to HEAD. Thanks!