Edit report at http://bugs.php.net/bug.php?id=54454&edit=1
ID: 54454 Updated by: s...@php.net Reported by: zweibieren at yahoo dot com Summary: substr_compare incorrectly reports equality in some cases Status: Re-Opened Type: Bug Package: Strings related Operating System: linux PHP Version: Irrelevant Assigned To: pierrick Block user comment: N Private report: N New Comment: I was initially concerned that the security implications of the patch were reviewed. Scott did this but has a concern about BC. Previous Comments: ------------------------------------------------------------------------ [2011-04-06 10:16:44] paj...@php.net Chris and Scott are seeing issues with this change. Reopening. ------------------------------------------------------------------------ [2011-04-03 09:23:04] pierr...@php.net This bug has been fixed in SVN. Snapshots of the sources are packaged every three hours; this change will be in the next snapshot. You can grab the snapshot at http://snaps.php.net/. Thank you for the report, and for helping us make PHP better. ------------------------------------------------------------------------ [2011-04-03 09:18:30] pierr...@php.net Automatic comment from SVN on behalf of pierrick Revision: http://svn.php.net/viewvc/?view=revision&revision=309910 Log: Fixed bug #54454 (substr_compare incorrectly reports equality in some cases) ------------------------------------------------------------------------ [2011-04-02 23:52:11] zweibieren at yahoo dot com Description: ------------ --- >From manual page: http://www.php.net/function.substr-compare#Description <blockquote> int substr_compare ( string $main_str , string $str , int $offset , int $length ... ) substr_compare() compares main_str from position offset with str up to length characters. Return Values Returns < 0 if main_str from position offset is less than str, > 0 if it is greater than str, and 0 if they are equal. ... </blockquote> --- HOWEVER, if main_str is shorter than str, substr_compare checks only up to the length of main_str. This is NOT how I read the description. I believe the comparison should extend to length characters and render a non-zero value if the two strings differ at any character in the first length characters. WORKAROUND: Use strncmp. {Note that substr_compare advertises itself as "binary safe." Since it is stopping at '\0', it fails to actually BE binary safe.} Test script: --------------- <html><head></head><body> <?php echo 'four comparisons of "/" and "/asd":' . '<br/> substr_compare("/", "/asd", 0, 4) => ' . substr_compare("/", "/asd", 0, 4) . ' <b>(SHOULD BE -3)</b>' . '<br/> substr_compare("/asd", "/", 0, 4) => ' . substr_compare("/asd", "/", 0, 4) . '<br/> strncmp("/", "/asd", 4) => ' . strncmp("/", "/asd", 4) . '<br/> strncmp("/asd", "/", 4) => ' . strncmp("/asd", "/", 4); ?> </body></html> Expected result: ---------------- four comparisons of "/" and "/asd": substr_compare("/", "/asd", 0, 4) => -3 substr_compare("/asd", "/", 0, 4) => 3 strncmp("/", "/asd", 4) => -3 strncmp("/asd", "/", 4) => 3 Actual result: -------------- four comparisons of "/" and "/asd": substr_compare("/", "/asd", 0, 4) => 0 (SHOULD BE -3) substr_compare("/asd", "/", 0, 4) => 3 strncmp("/", "/asd", 4) => -3 strncmp("/asd", "/", 4) => 3 As the script says, the first reported value should be -3. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=54454&edit=1