When buttons use a '#limit_validation_errors' = array($section) property, errors are reported only on elements where :
array_slice(explode('][', $name), 0, count($section)) === $section
That clause is never true for $sections containing numeric parts (i.e $form['foo'][0]['bar']), because the corresponding element will be '0' (string) in the left-side array, and 0 (numeric) in the right side array, which fails ===.
- would a simple == be OK there ?
- other than that, maybe reimplode both arrays into a string, and compare the strings ?
Comments
Comment #1
effulgentsia commentedGood catch. This should work:
I guess we need tests here.
Definitely "major" since field items have numeric indexes.
Comment #2
effulgentsia commentedActually, no! Because 0 == 'foo' is true. I guess rather than exploding $name, you can implode $section, and then compare as strings.
Comment #3
yched commentedYou mean something like
strpos($name, implode('][', $section)) === 0?Comment #4
yched commentedLike so ?
1st patch only adds a test showing the bug (should fail)
2nd patch is test + fix (should pass)
Comment #5
yched commentedbump ?
Comment #6
effulgentsia commented@yched: Sorry I've delayed so long on this. I was hoping to get some time to look at this in more detail, and maybe even help with a new patch, but since that hasn't happened, and since we're nearing RC, here's a cursory review. I think this issue is critical, since it may lead to a security vulnerability, though I haven't looked at it closely enough to know for sure if the existing bug can be exploited as a security hole.
I think this should probably be changed to
strpos($name . ']', $section_string . ']')or something like that, so that 'foobar' isn't considered "inside" 'foo'. We need a test for this as well, both at the top level, and a nested level, like 'parent][foo'.Is it really an edge case, if it happens within Field API?
Powered by Dreditor.
Comment #7
pifantastic commentedAdded the suggestion from @effulgentsia in #6 to prevent substrings from matching incorrectly. Also added a test for it.
Comment #8
pifantastic commentedMarking as needs review to trigger test.
Comment #9
chx commentedThis is the same patch as above but the change is the smallest possible to fix the problem. I like small changes, you know?
Comment #10
tstoecklerIn case of a reroll, patch contains trailing whitespace.
Comment #11
chx commentedDiscussing with webchick, actually we can throw out array_slice and just limit explode.
Comment #12
chx commented@tsoeckler , mine? The previous contained fixing whitespace which I skipped.
Comment #13
yched commented@effulgentsia : 'foo / foobar' : right, good catch. The $section_string needs a trailing ']', but I'm not sure the $name does.
The bug doesn't really happen within Field API for now - not until combofield is a reality.
Currently Field API's uses of #limit_validation_errors don't include numeric indexes (array paths do no go inside deltas)
The bug does however potentially affect any form structured with numeric indexes. How much of a sec hole this means is not too clear for me :-)
Comment #14
yched commented#13 was written in an open tab while #9-#12 were posted :-p
#11 looks just fine.
Comment #15
webchickOk, committed to HEAD!
Comment #16
duellj commentedUnfortunately this patch has totally broken top level validation with #limit_validation_errors, e.g.:
With the patch applied in #11, $form_state['values']['test']['inner'] is never validated, without the patch it is validated.
Comment #17
yched commentedexplode($foo, $bar, $limit) doesn't work :
"If limit is set and positive, the returned array will contain a maximum of limit elements *with the last element containing the rest of string*."
The array_slice(explode()) is needed - i.e. revert #11, commit #9.
Comment #18
yched commentedComment #19
duellj commentedpatch in #9 works and successfully validates children.
Comment #20
dries commentedCommitted to CVS HEAD. Thanks.