WordPress.org

Make WordPress Core

Ticket #48316: _wp_merge_trusted_paths.diff

File _wp_merge_trusted_paths.diff, 2.7 KB (added by mpcube, 7 months ago)

_wp_merge_trusted_paths()

  • wp-includes/functions.php

     
    22892289                $dir = WP_CONTENT_DIR . '/uploads';
    22902290        } elseif ( 0 !== strpos( $upload_path, ABSPATH ) ) {
    22912291                // $dir is absolute, $upload_path is (maybe) relative to ABSPATH
    2292                 $dir = path_join( ABSPATH, $upload_path );
     2292                if ( path_is_absolute( $upload_path ) ) {
     2293                        $dir = $upload_path;
     2294                } else {
     2295                        $dir = _wp_merge_trusted_paths( ABSPATH, $upload_path );
     2296                }
    22932297        } else {
    22942298                $dir = $upload_path;
    22952299        }
     
    22992303                if ( empty( $upload_path ) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) ) {
    23002304                        $url = WP_CONTENT_URL . '/uploads';
    23012305                } else {
    2302                         $url = trailingslashit( $siteurl ) . $upload_path;
     2306                        $url = _wp_merge_trusted_paths( $siteurl, $upload_path );
    23032307                }
    23042308        }
    23052309
     
    23082312         * We also sometimes obey UPLOADS when rewriting is enabled -- see the next block.
    23092313         */
    23102314        if ( defined( 'UPLOADS' ) && ! ( is_multisite() && get_site_option( 'ms_files_rewriting' ) ) ) {
    2311                 $dir = ABSPATH . UPLOADS;
    2312                 $url = trailingslashit( $siteurl ) . UPLOADS;
     2315                $dir = _wp_merge_trusted_paths( ABSPATH, UPLOADS );
     2316                $url = _wp_merge_trusted_paths( $siteurl, UPLOADS );
    23132317        }
    23142318
    23152319        // If multisite (and if not the main site in a post-MU network)
     
    23522356                        if ( defined( 'BLOGUPLOADDIR' ) ) {
    23532357                                $dir = untrailingslashit( BLOGUPLOADDIR );
    23542358                        } else {
    2355                                 $dir = ABSPATH . UPLOADS;
     2359                                $dir = _wp_merge_trusted_paths( ABSPATH, UPLOADS );
    23562360                        }
    23572361                        $url = trailingslashit( $siteurl ) . 'files';
    23582362                }
     
    23862390}
    23872391
    23882392/**
     2393 * Get an absolute path/directory/url of an absolute and a relative part
     2394 *
     2395 * Not to be used on untrusted input, as security checks rely on presence of '../' to detect unwanted path traversal.
     2396 *
     2397 * @param string $absolute_base absolute part
     2398 * @param string $relative_part relative part (may begin with '../')
     2399 * @return string  path/directory/url, absolute, merged
     2400 */
     2401function _wp_merge_trusted_paths( $absolute_base, $relative_part ) {
     2402        $one_parts = explode( '/', rtrim( $absolute_base, '/' ) );
     2403        while ( substr( $relative_part, 0, 3 ) == '../' ) {
     2404                $popped = array_pop( $one_parts );
     2405                if ( $popped === '' ) {
     2406                        // merge doesn't work. return $absolute_base instead
     2407                        return $absolute_base;
     2408                }
     2409                $relative_part = substr( $relative_part, 3 );
     2410        }
     2411        $absolute_base = implode( '/', $one_parts );
     2412        $relative_part = ltrim( $relative_part, '/' );
     2413        $all           = $absolute_base . '/' . $relative_part;
     2414
     2415        return $all;
     2416}
     2417
     2418/**
    23892419 * Get a filename that is sanitized and unique for the given directory.
    23902420 *
    23912421 * If the filename is not unique, then a number will be added to the filename