web-dev-qa-db-fra.com

Pourquoi wp_redirect supprime-t-il% 0A (caractère de nouvelle ligne codé dans l’URL) et comment puis-je le faire arrêter?

Cela a-t-il quelque chose à voir avec la désinfection? Je dois passer une chaîne en tant que paramètre d'URL. Cette chaîne contient\n caractères. Lorsque l'URL parvient au client, tous les autres encodages sont présents (les espaces apparaissent sous la forme +, les deux points sous la forme% 3A, etc.), mais pas les nouvelles lignes.

Voici le code pertinent:

wp_redirect("/upload_success?responseMsg=".urlencode($new_body->message));
1
the8thbit

Si vous examinez la fonction wp_sanitize_redirect(), vous remarquerez qu’elle supprime les nouvelles lignes de l’URL de destination:

https://core.trac.wordpress.org/browser/tags/4.9/src/wp-includes/pluggable.php#L1249

À mon avis, vous avez 2 options:

1 - Convertissez les nouvelles lignes du message en une combinaison de caractères unique autorisée par diff, puis replacez-les à nouveau avant la sortie de la chaîne à partir du paramètre URL responseMsg.

2 - Comme il s’agit d’une fonction pluggable , vous pouvez la placer dans un plugin et la personnaliser pour répondre à vos besoins. Quelque chose comme ça:

if ( !function_exists('wp_redirect') ) :
/**
 * Redirects to another page.
 *
 * Note: wp_redirect() does not exit automatically, and should almost always be
 * followed by a call to `exit;`:
 *
 *     wp_redirect( $url );
 *     exit;
 *
 * Exiting can also be selectively manipulated by using wp_redirect() as a conditional
 * in conjunction with the {@see 'wp_redirect'} and {@see 'wp_redirect_location'} hooks:
 *
 *     if ( wp_redirect( $url ) ) {
 *         exit;
 *     }
 *
 * @since 1.5.1
 *
 * @global bool $is_IIS
 *
 * @param string $location The path to redirect to.
 * @param int    $status   Status code to use.
 * @return bool False if $location is not provided, true otherwise.
 */
function wp_redirect($location, $status = 302, $strip_new_lines = true) {
    global $is_IIS;

    /**
     * Filters the redirect location.
     *
     * @since 2.1.0
     *
     * @param string $location The path to redirect to.
     * @param int    $status   Status code to use.
     */
    $location = apply_filters( 'wp_redirect', $location, $status );

    /**
     * Filters the redirect status code.
     *
     * @since 2.3.0
     *
     * @param int    $status   Status code to use.
     * @param string $location The path to redirect to.
     */
    $status = apply_filters( 'wp_redirect_status', $status, $location );

    if ( ! $location )
        return false;

    $location = wp_sanitize_redirect($location, $strip_new_lines);

    if ( !$is_IIS && PHP_SAPI != 'cgi-fcgi' )
        status_header($status); // This causes problems on IIS and some FastCGI setups

    header("Location: $location", true, $status);

    return true;
}
endif;

if ( !function_exists('wp_sanitize_redirect') ) :
/**
 * Sanitizes a URL for use in a redirect.
 *
 * @since 2.3.0
 *
 * @param string $location The path to redirect to.
 * @return string Redirect-sanitized URL.
 **/
function wp_sanitize_redirect($location, $strip_new_lines = true) {
    $regex = '/
        (
            (?: [\xC2-\xDF][\x80-\xBF]        # double-byte sequences   110xxxxx 10xxxxxx
            |   \xE0[\xA0-\xBF][\x80-\xBF]    # triple-byte sequences   1110xxxx 10xxxxxx * 2
            |   [\xE1-\xEC][\x80-\xBF]{2}
            |   \xED[\x80-\x9F][\x80-\xBF]
            |   [\xEE-\xEF][\x80-\xBF]{2}
            |   \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences   11110xxx 10xxxxxx * 3
            |   [\xF1-\xF3][\x80-\xBF]{3}
            |   \xF4[\x80-\x8F][\x80-\xBF]{2}
        ){1,40}                              # ...one or more times
        )/x';
    $location = preg_replace_callback( $regex, '_wp_sanitize_utf8_in_redirect', $location );
    $location = preg_replace('|[^a-z0-9-~+_.?#=&;,/:%!*\[\]()@]|i', '', $location);
    $location = wp_kses_no_null($location);

    // remove %0d and %0a from location
    $strip = array('%0d', '%0a', '%0D', '%0A');
    return $strip_new_lines ? _deep_replace( $strip, $location ) : $location;
}

/**
 * URL encode UTF-8 characters in a URL.
 *
 * @ignore
 * @since 4.2.0
 * @access private
 *
 * @see wp_sanitize_redirect()
 *
 * @param array $matches RegEx matches against the redirect location.
 * @return string URL-encoded version of the first RegEx match.
 */
function _wp_sanitize_utf8_in_redirect( $matches ) {
    return urlencode( $matches[0] );
}
endif;

Ensuite, vous pouvez appeler:

// by default is removing new lines so we pass false
$strip_new_lines = false;
$location = "/upload_success?responseMsg=".urlencode($new_body->message);

// make sure you pass the correct HTTP 
// status here to prevent penalty or any  other SEO issue
$status = 302;

wp_redirect( $location, $status,  $strip_new_lines );
//  wp_redirect() does not exit automatically
exit;
2
Pabamato