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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: hacker at tjworld dot net
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2025 The PHP Group
All rights reserved.
Last updated: Fri May 09 11:01:28 2025 UTC