On Thu, Nov 24, 2011 at 2:04 PM, <de...@lucato.it> wrote:

> Thanks Ferenc
>
> Everything looks ok http://codepad.viper-7.com/JTXsGK
>
> Devis
>
>
here are the corner cases:
5.3: http://codepad.viper-7.com/nPLorU
5.4: http://codepad.viper-7.com/MUdAlc

as you can see from the 4th example, your test will have an unexpected
result, if your $widget_options['dashboard_incoming_links'] is a string,
instead of an array, and it's first character is the same as
your get_option('home') return value.
this is because for string offsets the engine does a type juggling to int
for the index.

which is new in 5.4, that string offset chaining is supported, so as you
can see in the 5th example, your check will also fail if $widget_options is
a string instead of an array, and it's first character is the same as
your get_option('home') return value.

(this won't happen if your expected to be array variable is an empty
string, because isset($empty_string[0]) is false.)

another thing that I noticed while playing around:
in 5.3 the following code works:
$foobar = 'foobar';
isset($foobar['foo']);
isset($foobar['foo']['bar']);
echo $foobar['foo'];

but the following will trigger the fatal error:
isset($foobar['foo']['bar']['baz']);
echo $foobar['foo']['bar'];

So isset in 5.3 isn't immune to the fatal error, just it needs one more
chain to trigger it.
Which means that it is less likely to bump into this bug than I thought.

$string = 'foobar';
var_dump(isset($string['foo'])); // this behaves the same, both 5.3 and 5.4
returns true
var_dump($string['foo']); // this behaves the same, both 5.3 and 5.4
returns $string[0] -> 'f'
var_dump(isset($string['foo']['bar'])); // this behaves differently, 5.3
returns false but 5.4 returns true
var_dump($string['foo']['bar']); // this behaves differently, 5.3 fatals
but 5.4 returns $string[0] -> 'f'

5.3:
http://codepad.viper-7.com/yLajg6

5.4:
http://codepad.viper-7.com/S8Q7DG

Additional chaining will produce fatal errors in 5.3 (both for accessing
and calling isset) and will work in 5.4.
So there are only 2 cases, where 5.4 is different from 5.3, and the one of
them was throwing fatal error in 5.3, and I think that making it work
wouldn't count as a BC break.
Which means that there is only one single case which changes existing
behavior(breaks BC) and that is isset($string['foo']['bar']) the exact same
case that Daniel reported.

Another thing:
In 5.4 accessing arrays and strings through indexes/offsets have some
inconsistencies:
- isset($array[0][0][0][0]..[0]) will always return true for strings, but
that's not true for arrays.
- $array[0][0][0][0]..[0] will produce a notice for arrays(undefined
index), but that's not true for strings.

This is of course because they are different things, I'm just stating there
for the sake of completeness.

So I think if we could lessen/negate the impact of that single case, this
change wouldn't have BC issues.

ps:
I think that we can all agree that $foo[1][0] makes sense if $foo is an
array, but it isn't really useful if $foo is a string (as it will return
the same character as $foo[1][0]).

The other improvement (related but not introduced in this change) that I
suggested was that we could also trigger a notice when a "non-applicable"
string offset is passed(defining non-applicable is a little bit hard,
because of the current type-juggling rules, we have to allow $string["1"],
because '1" can come from a database, or get/post, where it would be a
string, not an int, but if we go with the current type juggling,
$string["2_foo_3"] would also be converted to $string[2], which isn't
really intended imo. .

Sorry for the long mail.
-- 
Ferenc Kovács
@Tyr43l - http://tyrael.hu

Reply via email to