kaiser
  • 0
Гуру

Смягчить неэкранированную HTML-фильтрацию внутри тегов ?

  • 0

По умолчанию WordPress удаляет любой контент, который может быть неэкранированным HTML, в комментариях незарегистрированных пользователей, что хорошо для защиты от XSS, но также излишне расширяет эту фильтрацию на <pre> элементы. В моем блоге, где почти каждый пост генерирует комментарии, которые выигрывают от фрагментов HTML-кода, эта фильтрация доставила моим пользователям (и мне) множество неприятностей.

Есть ли способ «исправить» эту чрезмерно агрессивную фильтрацию внутри <pre> элементов в незарегистрированных комментариях, не отключая ее для остальной части комментария? Предпочтительно, таким образом, чтобы выжить обновления.

Share
  1. небольшой раствор; выделение было в моем блоге через javascript

    function pre_esc_html($content) {
      return preg_replace_callback(
        '#(<pre.*?>)(.*?)(</pre>)#imsu',
        create_function(
          '$i',
          'return $i[1].esc_html($i[2]).$i[3];'
        ),
        $content
      );
    }
    
    add_filter(
      'the_content',
      'pre_esc_html',
      9
    );
    
    • 0
  2. Хотя это может быть немного больше, чем вы ищете, WP-Syntax отключает фильтрацию HTML в <pre> тегах внутри сообщений и комментариев (AFAIK). Он также работает для WordPress 3.0, хотя на веб-сайте указано, что он работает только с 2.8.

    Если вы хотите сделать это проще, я предлагаю заглянуть в wp-syntax.php плагин (особенно в самый низ, где они используют add_filters(), чтобы увидеть, как они отключают автоматическую фильтрацию HTML в WordPress в <pre> тегах. Затем вы можете применить это к комментариям.

    РЕДАКТИРОВАТЬ: я просмотрел файл, и они используют регулярное выражение и PHP preg_replace_callback() для сохранения исходного HTML в <pre> тегах. Возможно, вам придется изменить его в соответствии с вашими потребностями.

    У вас было бы, например (примечание: непроверенный код):

    <?php
    // Unique string for placeholder
    $custom_token = md5(uniqid(rand()));
    
    // Store all the matches in an array
    $custom_matches = array();
    
    function custom_substitute(&$match) {
        global $custom_token, $custom_matches;
    
        $i = count($custom_matches);
    
        // Store the match for later use
        $custom_matches[$i] = $match;
    
        // Unique placeholder so that we know where to put the code that was ripped out
        return '<p>' . $custom_token . '</p>';
    }
    
    function custom_replace($match) {
        global $custom_matches;
    
        $i = intval($match[1]);
        $match = $custom_matches[$i];
    
        // The index might be off - you might want to double-check it
        return htmlentities($match[1]);
    }
    
    function custom_before_content_filter($content) {
        return preg_replace_callback("/\s*<pre+>(.*)<\/pre>\s*/siU", 'custom_substitute', $content);
    }
    
    function custom_after_content_filter($content) {
        global $custom_token;
    
        return preg_replace_callback("/<p>\s*" . $custom_token . "\s*<\/p>/si", 'custom_replace', $content);
    }
    // Run the "before" filter first, with priority of 0
    add_filter('comment_text', 'custom_before_content_filter', 0);
    
    // Now run the "after" filter
    add_filter('comment_text', 'custom_after_content_filter', 99);
    
    • 0

Оставить ответ

You must login to add an answer.