WP_REST_Attachments_Controller::get_attachment_upload_subdir( string $attached_file ): string|null

Returns the uploads subdirectory an attachment is stored in.

Description

Used to place a sideloaded file alongside the attachment it extends. The result is concatenated into a filesystem path by the caller, so it is returned only when the attachment resolves inside the uploads directory and the stored path is well formed.

Parameters

$attached_filestringrequired
Absolute path to the attached file.

Return

string|null Subdirectory beginning with a slash, an empty string when the attachment sits in the base directory, or null when the attachment is not inside the uploads directory.

Source

protected function get_attachment_upload_subdir( string $attached_file ): ?string {
	$uploads = wp_get_upload_dir();
	if ( empty( $uploads['basedir'] ) ) {
		return null;
	}

	$basedir  = untrailingslashit( wp_normalize_path( $uploads['basedir'] ) );
	$file_dir = wp_normalize_path( dirname( $attached_file ) );

	/*
	 * The attachment's directory must be the uploads base directory itself
	 * or a directory inside it. The trailing slash in the prefix comparison
	 * keeps a sibling directory that merely shares the prefix (for example
	 * 'uploads-elsewhere' next to 'uploads') from matching.
	 */
	if ( $file_dir !== $basedir && ! str_starts_with( $file_dir, trailingslashit( $basedir ) ) ) {
		return null;
	}

	$subdir = (string) substr( $file_dir, strlen( $basedir ) );

	// A prefix match alone does not rule out a path that climbs back out.
	if ( in_array( '..', explode( '/', $subdir ), true ) ) {
		return null;
	}

	return $subdir;
}

Changelog

VersionDescription
7.1.0Introduced.

User Contributed Notes

You must log in before being able to contribute a note or feedback.