阻止WordPress转义短代码属性

时间:2017-07-30 19:42:44

标签: wordpress escaping hook shortcode

目前我正在开发一个插件,它连接到内容编辑器。我的回调在编辑后收到帖子内容并调用do_shortcode(),但是有一个问题,我不知道如何解决它。

add_filter('wp_insert_post_data',   'prepareContentSaving', 99, 2);
add_filter('wp_update_post_data',   'prepareContentSaving', 99, 2);

例如,如果我的帖子看起来像(显然看起来像有效的短代码语法):

[foo bar="two words"]

我的回调收到:

[foo bar=\"two words\"]

看起来对,对吗?但是现在每当通过do_shortcode()解析短代码时,参数就会被解析为

[tag argument1=value1 argument2]

而不是

[tag argument="Foo bar"]

然后在PHP中看起来像这样:

array(
[0]=>   string "bar=\"two"
[1]=>   string "words\""
)

那么如何防止短代码中的引号被转义? post数据钩子有问题吗?将优先级从99更改为0也不会改变某些内容。我使用的是正确的过滤器吗?

2 个答案:

答案 0 :(得分:1)

您可以尝试修改代码:

$post = array_map('stripslashes_deep', $_POST);

更多信息链接:http://codex.wordpress.org/Function_Reference/stripslashes_deep

答案 1 :(得分:0)

WordPress实际上并没有任何防止短代码转义的选项。唯一的方法是撤消它是转换所有' \"'回到'"' (函数中的单引号相同)&prepare;准备保存':

add_filter('wp_insert_post_data',   'prepareContentSaving', 99, 2);
add_filter('wp_update_post_data',   'prepareContentSaving', 99, 2);



function prepareContentSaving($data, $post) {
  $content = $post['post_content'];
  $content = correctShortcodeSlashes($content);

  ... any further processing ...

  $data['post_content'] = $content;
  return $data;
}

保存后的wordpress后,不仅可以转义引号,还可以转义反斜杠。所以'"'成为' \"'和' \"' (如果编辑想要逃避报价)变成' \\"'。

第一个给定的PCRE将短代码括号内的所有单个转义引号转换回正常引号,第二个转换为括号内的所有双转义引号。这样内容保持不变,这降低了代码注入的可能性。

PHP Manual on preg_replace

function correct_shortcode_slashes($text) {
  $attribute_escaped_slashes_pattern = '/(\[)((.|\s)*?)([^\\\\])\\\\("|\')(.*?)(\])/';
  $attribute_escaped_slashes_replacement = '$1$2$4"$6$7';

  $attribute_double_slashes_pattern = '/(\[)((.|\s)*?)\\\\+("|\')(.*?)(\])/';
  $attribute_double_slashes_replacement = '$1$2"$5$6';

  $result = $text;
  $counter = 0;
  while(true) {
    $result = preg_replace($attribute_escaped_slashes_pattern, $attribute_escaped_slashes_replacement, $result, -1, $counter);
    if($counter === 0) {
        break;
    }
  }
  while(true) {
    $result = preg_replace($attribute_double_slashes_pattern, $attribute_double_slashes_replacement, $result, -1, $counter);
    if($counter === 0) {
        break;
    }
  }
  return $result;
}

请随时加强此答案。