逃避角色 [英] Escaping escape Characters

查看:134
本文介绍了逃避角色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图模仿PHP 5.3.0中实现的 json_encode 位掩码标志,这里是我所用的字符串:

  $ s = addslashes('O\'Reilly'); // O\'Rei\lly 

执行 json_encode($ s,JSON_HEX_APOS | JSON_HEX_QUOT)输出以下内容:

 O\\\'Rei\\\U0022lly
/ pre>

我目前正在使用5.3.0以前的PHP版本:

  str_replace(array('\\'','\\\''),array('\\\\"','\\\\\''),json_encode ($ s))

str_replace(array('\\'','\\\''),array('\\\\"','\ \\\\''),json_encode($ s))

哪个正确输出相同的结果:

 O\\\'Rei\\\u0 022lly

我无法理解为什么我需要替换单引号('\\\\''甚至\\ [ c $ c \\'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ c>






以下是我无法移植到PHP的代码; 5.3:

  if(get_magic_quotes_gpc()&& version_compare(PHP_VERSION,'6.0.0' <'))
{
/ * JSON_HEX_APOS和JSON_HEX_QUOT可用* /
if(version_compare(PHP_VERSION,'5.3.0','> =')=== true)
{
$ _GET = json_encode($ _ GET,JSON_HEX_APOS | JSON_HEX_QUOT);
$ _POST = json_encode($ _ POST,JSON_HEX_APOS | JSON_HEX_QUOT);
$ _COOKIE = json_encode($ _ COOKIE,JSON_HEX_APOS | JSON_HEX_QUOT);
$ _REQUEST = json_encode($ _ REQUEST,JSON_HEX_APOS | JSON_HEX_QUOT);
}

/ *模仿JSON_HEX_APOS和JSON_HEX_QUOT * /
的行为else if(extension_loaded('json')=== true)
{
$ _GET = str_replace(array(),array('\\\\"','\\''),json_encode($ _ GET));
$ _POST = str_replace(array(),array('\\\\"','\\''),json_encode($ _ POST));
$ _COOKIE = str_replace(array(),array('\\\\"','\\''),json_encode($ _ COOKIE));
$ _REQUEST = str_replace(array(),array('\\\\"','\\''),json_encode($ _ REQUEST));
}

$ _GET = json_decode(stripslashes($ _ GET));
$ _POST = json_decode(stripslashes($ _ POST));
$ _COOKIE = json_decode(stripslashes($ _ COOKIE));
$ _REQUEST = json_decode(stripslashes($ _ REQUEST));
}


解决方案

PHP字符串

 'O\'Reilly'

只是PHP获取字面值的方式

  O'Reilly 

到一个可以使用的字符串。在该字符串上调用 addslashes 将其替换为以下11个字符

  O \'Rei \lly 

ie strlen(addslashes( 'O\'Reilly'))== 11



这是发送到 json_escape 。



JSON反斜杠是一个转义字符,所以需要转义,即



\ \\



单引号和双引号也可能导致问题。因此,以一种方式将它们转换为unicode等价物,以避免问题。所以后来的PHP的json_encode的变化



' \\\'





\\\"



所以将这三条规则应用于

  O\Rei\lly 

给我们

  O\\\'Rei\\\\\0000 $ c> 

然后,该字符串用双引号括起来使其成为一个JSON字符串。您的替换表达式包括前导斜杠。无论是意外还是故意,这意味着 json_encode 返回的前导和尾随双引号不受转义的限制,不应该是。\\ / p>

所以在早期版本的PHP

  $ s = addslashes('O\' Reilly); 
打印json_encode($ s);

p>

 O\\Rei \\\lly

,我们要将'更改为 \\\'
,我们要将 \更改为 \\\" ,因为 \ \只是为了获得进入字符串,因为它开始并以双引号结尾。



所以这就是为什么我们得到



<$ p $ $$$$

I'm trying to mimic the json_encode bitmask flags implemented in PHP 5.3.0, here is the string I have:

$s = addslashes('O\'Rei"lly'); // O\'Rei\"lly

Doing json_encode($s, JSON_HEX_APOS | JSON_HEX_QUOT) outputs the following:

"O\\\u0027Rei\\\u0022lly"

And I'm currently doing this in PHP versions older than 5.3.0:

str_replace(array('\\"', "\\'"), array('\\u0022', '\\\u0027'), json_encode($s))
or
str_replace(array('\\"', '\\\''), array('\\u0022', '\\\u0027'), json_encode($s))

Which correctly outputs the same result:

"O\\\u0027Rei\\\u0022lly"

I'm having trouble understanding why do I need to replace single quotes ('\\\'' or even "\\'" [surrounding quotes excluded]) with '\\\u0027' and not just '\\u0027'.


Here is the code that I'm having trouble porting to PHP < 5.3:

if (get_magic_quotes_gpc() && version_compare(PHP_VERSION, '6.0.0', '<'))
{
    /* JSON_HEX_APOS and JSON_HEX_QUOT are availiable */
    if (version_compare(PHP_VERSION, '5.3.0', '>=') === true)
    {
        $_GET = json_encode($_GET, JSON_HEX_APOS | JSON_HEX_QUOT);
        $_POST = json_encode($_POST, JSON_HEX_APOS | JSON_HEX_QUOT);
        $_COOKIE = json_encode($_COOKIE, JSON_HEX_APOS | JSON_HEX_QUOT);
        $_REQUEST = json_encode($_REQUEST, JSON_HEX_APOS | JSON_HEX_QUOT);
    }

    /* mimic the behaviour of JSON_HEX_APOS and JSON_HEX_QUOT */
    else if (extension_loaded('json') === true)
    {
        $_GET = str_replace(array(), array('\\u0022', '\\u0027'), json_encode($_GET));
        $_POST = str_replace(array(), array('\\u0022', '\\u0027'), json_encode($_POST));
        $_COOKIE = str_replace(array(), array('\\u0022', '\\u0027'), json_encode($_COOKIE));
        $_REQUEST = str_replace(array(), array('\\u0022', '\\u0027'), json_encode($_REQUEST));
    }

    $_GET = json_decode(stripslashes($_GET));
    $_POST = json_decode(stripslashes($_POST));
    $_COOKIE = json_decode(stripslashes($_COOKIE));
    $_REQUEST = json_decode(stripslashes($_REQUEST));
}

解决方案

The PHP string

'O\'Rei"lly'

is just PHP's way of getting the literal value

O'Rei"lly

into a string which can be used. Calling addslashes on that string changes it to be literally the following 11 characters

O\'Rei\"lly

i.e. strlen(addslashes('O\'Rei"lly')) == 11

This is the value which is being sent to json_escape.

In JSON backslash is an escape character, so that needs to be escaped, i.e.

\ to be \\

Also single and double quotes can cause problems. So converting them to their unicode equivalent in one way to avoid problems. So later verions of PHP's json_encode change

' to be \u0027

and

" to be \u0022

So applying these three rules to

O\'Rei\"lly

gives us

O\\\u0027Rei\\\u0022lly

This string is then wrapped in double quotes to make it a JSON string. Your replace expressions include the leading forward slashes. Either by accident or on purpose this means that the leading and trailing double quote returned by json_encode is not subject to the escaping, which it shouldn't be.

So in earlier versions of PHP

$s = addslashes('O\'Rei"lly');
print json_encode($s);

would print

"O\\'Rei\\\"lly"

and we want to change ' to be \u0027 and we want to change \" to be \u0022 because the \ in \" is just to get the " into the string because it begins and ends with double-quotes.

So that's why we get

"O\\\u0027Rei\\\u0022lly"

这篇关于逃避角色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆