Anonymous | Login | Signup for a new account | 11-22-2024 03:23 PST |
Main | My View | View Issues | Change Log | Docs |
Viewing Issue Advanced Details [ Jump to Notes ] | [ View Simple ] [ Issue History ] [ Print ] | |||||||||||
ID | Category | Severity | Reproducibility | Date Submitted | Last Update | |||||||
0004059 | [Quercus] | block | always | 06-01-10 09:13 | 06-08-10 08:26 | |||||||
Reporter | sblommers | View Status | public | |||||||||
Assigned To | ||||||||||||
Priority | normal | Resolution | open | Platform | Linux | |||||||
Status | new | OS | Ubuntu | |||||||||
Projection | none | OS Version | 10.04 | |||||||||
ETA | none | Fixed in Version | Product Version | 4.0.8 | ||||||||
Product Build | SVN | |||||||||||
Summary | 0004059: PHP Type comparison not the same | |||||||||||
Description |
Differences in type comparison between Quercus and PHP that are possibly causing most incompatibilities in existing PHP applications running on Quercus. Some of the type checks that are different on Quercus are causing major inconsistencies in data (I filed some bugs for Drupal). |
|||||||||||
Steps To Reproduce |
Run this script on both PHP and Quercus and see the difference (or download from https://streamconsulting.nl/drop/php-type-comparison.php) [^] <?php $tests = array(); /* Testing equalty */ $tests['=='] = create_function('$a, $b', 'return $a==$b;'); $tests['!='] = create_function('$a, $b', 'return $a!=$b;'); $tests['<>'] = create_function('$a, $b', 'return $a<>$b;'); $tests['<'] = create_function('$a, $b', 'return $a<$b;'); $tests['>'] = create_function('$a, $b', 'return $a>$b;'); $tests['<='] = create_function('$a, $b', 'return $a<=$b;'); $tests['>='] = create_function('$a, $b', 'return $a>=$b;'); /* Testing identity */ $tests['==='] = create_function('$a, $b', 'return $a===$b;'); $tests['!=='] = create_function('$a, $b', 'return $a!==$b;'); $comparison = array(); $comparison['TRUE'] = true; $comparison['FALSE'] = false; $comparison['1'] = 1; $comparison['0'] = 0; $comparison['-1'] = -1; $comparison['3,14'] = pi(); $comparison['"1"'] = '1'; $comparison['"0"'] = '0'; $comparison['"-1"'] = '-1'; $comparison['NULL'] = null; $comparison['array()'] = array(); $comparison['"php"'] = 'php'; print '<h1>PHP version '.PHP_VERSION.' type comparison tables</h1>'; foreach ($tests as $test=>$function) { print "<h2>Comparisons with $test</h2>"; print "<table border='1'>"; print "<tr>"; print "<th> </th>"; foreach (array_keys($comparison) as $name) { print "<th>$name</th>"; } print "</tr>"; foreach ($comparison as $arg_1_name => $arg_1_value) { print '<tr>'; print "<th>$arg_1_name</th>"; foreach ($comparison as $arg_2_value) { print '<td>'; print $function($arg_1_value, $arg_2_value)==true ? '<span style="color:00F;">TRUE</span>' : '<span style="color:#F00;">FALSE</span>'; print '</td>'; } print "</tr>"; } print "</table>"; } ?> |
|||||||||||
Additional Information | ||||||||||||
Attached Files | ||||||||||||
|
Notes | |
(0004635) sblommers 06-08-10 08:26 |
It took me some time but I managed to workaround every incorrect comparison and created a diff. https://streamconsulting.nl/drop/Value_TypeChecking_4059.diff [^] diff -r 9ce0fb81b2de modules/quercus/src/com/caucho/quercus/env/ArrayValue.java --- a/modules/quercus/src/com/caucho/quercus/env/ArrayValue.java Fri Jun 04 10:57:18 2010 +0200 +++ b/modules/quercus/src/com/caucho/quercus/env/ArrayValue.java Tue Jun 08 17:23:30 2010 +0200 @@ -613,13 +613,25 @@ // arrays are uncomparable, otherwise - compare value by value" // php/335h + + if (rValue.isBoolean() || rValue.isNull()) { + boolean lBool = toBoolean(); + boolean rBool = rValue.toBoolean(); - if (!rValue.isArray()) - return 1; + if (! lBool && rBool) + return -1; + if (lBool && ! rBool) + return 1; - int lSize = getSize(); + return 0; + } + + if(!rValue.isArray()) + return 1; + + int lSize = getSize(); int rSize = rValue.toArray().getSize(); - + if (lSize != rSize) return lSize < rSize ? -1 : 1; @@ -1419,8 +1431,16 @@ return false; final Set<Map.Entry<Value,Value>> entryset = entrySet(); + if (rValue instanceof BooleanValue) - return entryset.size() > 0 ? rValue.toBoolean() : !rValue.toBoolean(); + return !entryset.isEmpty() ? rValue.toBoolean() : !rValue.toBoolean(); + + if(rValue instanceof ArrayValueImpl && entryset.isEmpty()) { + final Set<Map.Entry<Value,Value>> rentryset = ((ArrayValueImpl)rValue).entrySet(); + if(rentryset.size() > 0) + return false; + else return true; + } for (Map.Entry<Value, Value> entry: entryset) { Value entryValue = entry.getValue(); diff -r 9ce0fb81b2de modules/quercus/src/com/caucho/quercus/env/BooleanValue.java --- a/modules/quercus/src/com/caucho/quercus/env/BooleanValue.java Fri Jun 04 10:57:18 2010 +0200 +++ b/modules/quercus/src/com/caucho/quercus/env/BooleanValue.java Tue Jun 08 17:23:30 2010 +0200 @@ -262,7 +262,7 @@ public int cmp(Value rValue) { boolean rBool = rValue.toBoolean(); - + if (! _value && rBool) return -1; if (_value && ! rBool) diff -r 9ce0fb81b2de modules/quercus/src/com/caucho/quercus/env/LongValue.java --- a/modules/quercus/src/com/caucho/quercus/env/LongValue.java Fri Jun 04 10:57:18 2010 +0200 +++ b/modules/quercus/src/com/caucho/quercus/env/LongValue.java Tue Jun 08 17:23:30 2010 +0200 @@ -452,7 +452,7 @@ @Override public int cmp(Value rValue) { - if (rValue.isBoolean()) { + if (rValue.isBoolean() || rValue.isNull()) { boolean lBool = toBoolean(); boolean rBool = rValue.toBoolean(); @@ -463,7 +463,10 @@ return 0; } - + + if(rValue.isArray()) + return -1; + long l = _value; double r = rValue.toDouble(); diff -r 9ce0fb81b2de modules/quercus/src/com/caucho/quercus/env/NullValue.java --- a/modules/quercus/src/com/caucho/quercus/env/NullValue.java Fri Jun 04 10:57:18 2010 +0200 +++ b/modules/quercus/src/com/caucho/quercus/env/NullValue.java Tue Jun 08 17:23:30 2010 +0200 @@ -565,6 +565,9 @@ double l = 0; double r = rValue.toDouble(); + if(r <= 0) + return -1; + if (l == r) return 0; else if (l < r) diff -r 9ce0fb81b2de modules/quercus/src/com/caucho/quercus/env/NumberValue.java --- a/modules/quercus/src/com/caucho/quercus/env/NumberValue.java Fri Jun 04 10:57:18 2010 +0200 +++ b/modules/quercus/src/com/caucho/quercus/env/NumberValue.java Tue Jun 08 17:23:30 2010 +0200 @@ -40,6 +40,9 @@ @Override public int cmp(Value rValue) { + if(rValue.isArray()) + return -1; + if (rValue.isBoolean() || rValue.isNull()) { boolean lBool = toBoolean(); boolean rBool = rValue.toBoolean(); diff -r 9ce0fb81b2de modules/quercus/src/com/caucho/quercus/env/StringValue.java --- a/modules/quercus/src/com/caucho/quercus/env/StringValue.java Fri Jun 04 10:57:18 2010 +0200 +++ b/modules/quercus/src/com/caucho/quercus/env/StringValue.java Tue Jun 08 17:23:30 2010 +0200 @@ -384,9 +384,37 @@ */ public int cmp(Value rValue) { - if (isNumberConvertible() || rValue.isNumberConvertible()) { + if(rValue instanceof NullValue) + return cmpString(StringValue.EMPTY); + + if(rValue.isArray()) + return -1; + + if(rValue instanceof BooleanValue) { + boolean lBool = toBoolean(); + boolean rBool = rValue.toBoolean(); + + if (!lBool && rBool) return -1; + if (lBool && !rBool) return 1; + return 0; + } + + if (isNumberConvertible() || rValue.isNumberConvertible()) { + double l = toDouble(); double r = rValue.toDouble(); + + if((!rValue.isNumberConvertible() && rValue instanceof ConstStringValue)) + return -1; + + if((!isNumberConvertible() && rValue instanceof ConstStringValue)) + return 1; + + if(!isNumberConvertible() && l > 0) + return 1; + + if(l < 0 && (rValue instanceof NullValue || rValue instanceof BooleanValue)) + return 1; if (l == r) return 0; |
Issue History | |||
Date Modified | Username | Field | Change |
06-01-10 09:13 | sblommers | New Issue | |
06-08-10 08:26 | sblommers | Note Added: 0004635 |
Mantis 1.0.0rc3[^]
Copyright © 2000 - 2005 Mantis Group
29 total queries executed. 26 unique queries executed. |