php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #35334 strpos fails to match unescaped single-quotes passed via function
Submitted: 2005-11-22 16:44 UTC Modified: 2005-11-22 17:11 UTC
From: hacker at tjworld dot net Assigned:
Status: Not a bug Package: Strings related
PHP Version: 5.1.0RC6 OS: Windows XP Professional SP2
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
31 - 17 = ?
Subscribe to this entry?

 
 [2005-11-22 16:44 UTC] hacker at tjworld dot net
Description:
------------
strpos() is failing to match 'needle' when the part of haystack we're looking for contains single-quotes, AND the needle string is passed into a function that does the strpos() search, AND the needle string does not use escaped single-quotes.

The same strpos() search outside of the function scope works as expected.

This only occurs with

magic_quotes_runtime = On

but the docs for magic_quotes_runtime don't mention that strings being passed into functions will be affected, only strings returned...

http://uk.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime


TJ.


Reproduce code:
---------------
<?php
function findNeedle($file, $needle) {
  if (($f = fopen($file, 'r'))) {
   $content = fread($f, filesize($file));
   fclose($f);

  echo htmlspecialchars("Haystack: $content\n\n");
  $offsetStart = strpos($content, $needle);
  echo "From offset $offsetStart ->>>".htmlspecialchars($needle)."\n";
  if ($offsetStart === false)
   echo "Error, cannot find start offset.\n";
 }
}

$haystack="<tr><td class=\"main\"><?php echo TEXT_PRODUCTS_WEIGHT; ?></td><td class=\"main\"><?php echo tep_draw_separator('pixel_trans.gif', '24', '15') . '&nbsp;' . tep_draw_input_field('products_weight', \$pInfo->products_weight); ?></td></tr></table></td>";
$needle = "tep_draw_input_field('products_weight', \$pInfo->products_weight); ?></td>";

echo "<pre>This will find it - strpos() in same scope\n";
echo htmlspecialchars("Haystack: $haystack\n\n");

$offsetStart = strpos($haystack, $needle);
echo "From offset $offsetStart ->>>".htmlspecialchars($needle)."\n";
if ($offsetStart === false)
 echo "Error, cannot find start offset.\n";

if (($f = fopen('test.html', 'w'))) {
 // note: haystack contains excerpt from HTML source file, which is read from disk in the code where the problem was discovered
 // double-quotes are manually escaped here to pass grammar checks
 // dollar-signs escaped to prevent variable replacement
 fwrite($f, $haystack);
 fclose($f);

 echo "\n\nThis will fail to find it - strpos() in function scope\n";
 $needle = "tep_draw_input_field('products_weight', \$pInfo->products_weight); ?></td>";
 findNeedle('test.html',$needle);

 echo "\n\nThis will find it - added escaped single-quotes - strpos() in function scope\n";
 $needle = "tep_draw_input_field(\'products_weight\', \$pInfo->products_weight); ?></td>";
 findNeedle('test.html',$needle);

 echo "</pre>";
}
?>

Expected result:
----------------
All three searches should find the needle.

Actual result:
--------------
This will find it - strpos() in same scope
Haystack: <tr><td class="main"><?php echo TEXT_PRODUCTS_WEIGHT; ?></td><td class="main"><?php echo tep_draw_separator('pixel_trans.gif', '24', '15') . '&nbsp;' . tep_draw_input_field('products_weight', $pInfo->products_weight); ?></td></tr></table></td>

From offset 152 ->>>tep_draw_input_field('products_weight', $pInfo->products_weight); ?></td>


This will fail to find it - strpos() in function scope
Haystack: <tr><td class=\"main\"><?php echo TEXT_PRODUCTS_WEIGHT; ?></td><td class=\"main\"><?php echo tep_draw_separator(\'pixel_trans.gif\', \'24\', \'15\') . \'&nbsp;\' . tep_draw_input_field(\'products_weight\', $pInfo->products_weight); ?></td></tr></table></td>

From offset  ->>>tep_draw_input_field('products_weight', $pInfo->products_weight); ?></td>
Error, cannot find start offset.


This will find it - added escaped single-quotes - strpos() in function scope
Haystack: <tr><td class=\"main\"><?php echo TEXT_PRODUCTS_WEIGHT; ?></td><td class=\"main\"><?php echo tep_draw_separator(\'pixel_trans.gif\', \'24\', \'15\') . \'&nbsp;\' . tep_draw_input_field(\'products_weight\', $pInfo->products_weight); ?></td></tr></table></td>

From offset 164 ->>>tep_draw_input_field(\'products_weight\', $pInfo->products_weight); ?></td>


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-11-22 17:01 UTC] hacker at tjworld dot net
Okay, why is it the light-bulb only flashes after you've posted a bug report?

I noticed that the offset of the match is higher in the final match via function-call than in the first one done in local scope. The it dawned on me that with magic_quotes_runtime On, the string read from disk increases in length by one character for every escape that is inserted.

So the final test where it matches via function-call does so no because the escaped single-quote represents a single character-code, but because it literally matches two characters - backslash+single-quote \'

So, only a bug in my brain... although a damned confusing issue non-the-less!
 [2005-11-22 17:11 UTC] tony2001@php.net
.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 21:01:30 2024 UTC