php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #60401 Example 4 results in double quotes slashed
Submitted: 2011-11-28 06:32 UTC Modified: 2011-12-04 21:56 UTC
From: jf at jonathanfoote dot com Assigned: frozenfire (profile)
Status: Closed Package: Documentation problem
PHP Version: 5.3.8 OS: Windows
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: jf at jonathanfoote dot com
New email:
PHP Version: OS:

 

 [2011-11-28 06:32 UTC] jf at jonathanfoote dot com
Description:
------------
---
From manual page: http://www.php.net/function.preg-replace
---
Example #4 from preg_replace() it states:

This would capitalize all HTML tags in the input text.

But it does not mention that double quotes would get slashes added.  Using the 
example would result in the text:

<div class="test">

to be converted to:

<DIV class=\"test\">

The tag is indeed converted to uppercase as it states, but slashes are added to 
double quotes.  See below for perhaps a more robust example that accounts for 
this (basically run the rest through str_replace() that replaces \" with ").

Test script:
---------------
<?php

$html_body = '<div class="test">';
//Solution from example #4
$html_upper = preg_replace("/(<\/?)(\w+)([^>]*>)/e", 
             "'\\1'.strtoupper('\\2').'\\3'", 
             $html_body);

echo $html_upper;
//resulted output: <DIV class=\"test\">

//Better solution:
$html_upper = preg_replace("/(<\/?)(\w+)([^>]*>)/e", 
             "'\\1'.strtoupper('\\2').str_replace('\\\"','\"','\\3')", 
             $html_body);
echo $html_upper;
//resulted output: <DIV class="test">

?>


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-12-03 04:28 UTC] frozenfire@php.net
Automatic comment from SVN on behalf of frozenfire
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=320298
Log: Clarified e-modifier example behavior, as per bug #60401.
 [2011-12-03 04:28 UTC] frozenfire@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: frozenfire
 [2011-12-03 04:28 UTC] frozenfire@php.net
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation better.


 [2011-12-03 07:31 UTC] jf at jonathanfoote dot com
Since it surrounds \\3 with single quotes, the end resulting string does not have 
single quotes escaped, just double quotes and I assume null.  If for example, you 
were to run example #4 on the following:

<div class="test" style='display: none;'>

result:
<DIV class=\"test\" style='display: none;'>
 [2011-12-04 20:41 UTC] frozenfire@php.net
-Status: Closed +Status: Re-Opened
 [2011-12-04 20:59 UTC] frozenfire@php.net
I'm finding that it doesn't escape any of the quotes at all. That seems to be 
because the backreference that's being run through the strtoupper function is 
does not contain either of the tag's attributes.

It would only escape any quotes in the tag name, it would seem.

<?php
$html_body = "<div class=\"test\" style='display: none;' >";
preg_replace("/(<\/?)(\w+)([^>]*>)/e", 
             "'\\1'.strtoupper('\\2').'\\3'", 
             $html_body);

echo $html_body;

// Outputs: <div class="test" style='display: none;'>
 [2011-12-04 21:01 UTC] frozenfire@php.net
Err, just after writing that, I felt really silly. I forgot to assign the result 
of the preg_replace to a function. It does seem you're right, but I cannot figure 
out why.
 [2011-12-04 21:35 UTC] frozenfire@php.net
After seeking some clarification from others, it would seem that eval modifier 
is completely idiotic. Pardon my wording, but it really is.

Since it's escaping slashes, and the string is being placed in single quotes in 
the replace statement, the single quotes get slashed, then it looks like this: 
'\''

So you end up with literal single quotes with no slash

Whereas the double-quotes end up like: '\"'

Which is a double-quote still slashed.

Any example I can give will either avoid using quotes, or will confuse the hell 
out of people.
 [2011-12-04 21:41 UTC] hello at apfelbox dot net
You could just advise people to use preg_replace_callback() instead of preg_replace() with the modifier e. It is also safer, because preg_replace() with modifier does imply the eval(), which is considered unsafe (if you are dealing with user input here).
 [2011-12-04 21:56 UTC] frozenfire@php.net
-Status: Re-Opened +Status: Closed
 [2011-12-04 21:56 UTC] frozenfire@php.net
I'd forgotten to include the bug in my commit message. The revision is 320388.

I removed the eval example in preg_replace's reference, and added a caution to 
the eval modifier's reference.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon May 06 13:01:31 2024 UTC