3

We recently upgraded to php 5.4.15, and it does not have magic quotes on as default. It was time :)

But it turns out wp is adding its own slashes to POST and everything, for its internal compatibility reasons.

Now in a lot of plugins, I had some sensible functions that would strip slashes IF they were added by php:

function POSTGET_stripslashes_all($forced=false)
    {
    if(!get_magic_quotes_gpc() and !get_magic_quotes_runtime()) if(!$forced) return;
    ....

But wp adds slashes regardless of php settings, So I ended up stripping slashes ALWAYS regardless of any settings. Problem is, what if user wanted to use literal slashes in its input?

How to bring some sense into this? I do not want to strip slashes always. How did you approach this? Do you just give up and strip everything when it comes to wp? Is there a nice rule of thumb that says where and where not wp slashes things?

Johan
  • 637
  • 7
  • 11

1 Answers1

4

Well, I had to discover my own answer.

file: wp-settings.php > function wp_magic_quotes() is called. 
  • this file is almost included when wp is run, is included unconditionally by wp-config.php.
  • the function call is before almost everything,
  • BUT called after advanced-cache.php
  • AND after action hook do_action( 'plugins_loaded' ).

the function itself:

function wp_magic_quotes() (is in file wp-includes/load.php) 
     {
     if(get_magic_quotes_gpc()) strip_slashes()
     adds slashes to POST, GET, COOKIES and SERVER, using add_magic_quotes()
     }

so if you need to decide whether to strip slashes or not, use:

if(!get_magic_quotes_gpc() and !function_exists('wp_magic_quotes')) do_not_strip;

And here is the full form function:

function POSTGET_stripslashes_all($forced=false)
    {
    global $POSTGET_stripslashes_all_done;
    if(!get_magic_quotes_gpc() and !function_exists('wp_magic_quotes')) if(!$forced) return;//wp check
    if($POSTGET_stripslashes_all_done) return;
    //stripslashes
    if(is_array($_POST))    $_POST=POSTGET_stripslashes_deep($_POST,$forced);
    if(is_array($_GET)) $_GET=POSTGET_stripslashes_deep($_GET,$forced);
    if(is_array($_REQUEST)) $_REQUEST=POSTGET_stripslashes_deep($_REQUEST,$forced);
    $POSTGET_stripslashes_all_done=true;
    }



function POSTGET_stripslashes_deep($value,$forced=false)
    {
    global $POSTGET_stripslashes_all_done;
    if(!get_magic_quotes_gpc() and !function_exists('wp_magic_quotes')) if(!$forced) return $value;
    if($POSTGET_stripslashes_all_done) if(!$forced) return $value;
    if(is_string($value)) return  stripslashes($value);
    if(is_array($value))
        foreach($value as $name=>$val)
            $value[$name]=POSTGET_stripslashes_deep($val,$forced);
    return $value;
    }
Johan
  • 637
  • 7
  • 11
  • 1
    What are you talking about, 'the code is not valid'? Let's make useful comments, this is stackoverflow not a chat room. – Johan Nov 28 '13 at 18:11
  • 2
    There were some comments without any `//`, which made it not runnable as PHP code. Not valid PHP code. But actually the function makes sense, it was only hard to read. I originally wanted to upvote it but it was so hard to read that I gave up the last time. I'll upvote it now anyway... ...I now just use `stripslashes()` on all posted data in WP, and if I want to be certain about it I would package the data on the client side with javascript into BASE64 and send it like that and unpack on the server. That way I can be certain that WP or PHP doesn't add any slashes to it. – gregn3 Dec 03 '13 at 19:02