Make WordPress Core

Opened 4 years ago

Closed 15 months ago

#52844 closed defect (bug) (duplicate)

wp_tempnam [download_url] unable to create temporary file if file name is too long

Reported by: nextendweb's profile nextendweb Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Filesystem API Keywords: reporter-feedback
Focuses: Cc:

Description

If the first parameter of the wp_tempnam function is too long, then the temporary file could not be created as filesystems has limit to the path and the file name length.

This mainly impacts download_url function which takes an url argument and tries to create temporary file based on basename( parse_url( $url, PHP_URL_PATH ) )

For example this url points to a Google avatar:

https://lh3.googleusercontent.com/a-/AOh14Gglfqpi2Kz6aFTysWWgDnP2PszwkmL55tl4QNSX62jNTt-GK7ERhWuIT9AehHIzIlTdxBrNUUeWLwGyZeqsM3W300OX8xDy6lOmUMIChjOUMmfM1qHUKRbpZmElOXyT4DNLJiixrPuwkAH24sy5cQLtp8YPhdKR1SrErcXzFLjO1EQ2JvgLFvihaL92ddDERbdFVziBgsl9R0VDplz-EX2Qr3q5ieaJ3d8pXBA-DyZB5FSQWx1RHUBXECE7CFGGKORHYwNrrJnvh8P57TlrdfYFNvzmPgoUJFGl7WITIKG7saB3nhdY2j9MdQ4j1a1lH-QuK6p_Pz1fYYJVHQEmYRhMWOXExh675j7k3xB4NYRbPnpKFjinayfkWNq7aZg5dfX0Pv_ZjhO9crZnpqAbfATL5DxG0zomMtY4KZqma3qKLq3MXpijXqD4vshMheoo90IcTKOUkopcP7RFES-R3TXb-R_JtNUQ-Uw-Wc41t03ySkvM4U8nuPX_XZ3nzc6fLlHtRKC0dw5Bm7cELv7Nb1YgSVIAqJveQ_QtzSwfbJo9-wXDgjv13jA24l34IPbieVfXJ2LIExKVuptVyfKy4G8FndRlMRbhhsAeQuHw6l3dmSxD8VOVfCTa3YPCFyQ66AI_B2ALHRwbdibkxI_DBhuH2WDZxHD8jPhKK0GrcPniIbIR0QwsZ7NBNGBQNGD4c3nf0xeYQQTr8VzteRhEpz2ERXiGboqslL10qTch8s7pz_mu5Xqty2Izs7Xm6vowIKAEYA=s96-c

The argument for wp_tempnam will be AOh14Gglfqpi2Kz6aFTysWWgDnP2PszwkmL55tl4QNSX62jNTt-GK7ERhWuIT9AehHIzIlTdxBrNUUeWLwGyZeqsM3W300OX8xDy6lOmUMIChjOUMmfM1qHUKRbpZmElOXyT4DNLJiixrPuwkAH24sy5cQLtp8YPhdKR1SrErcXzFLjO1EQ2JvgLFvihaL92ddDERbdFVziBgsl9R0VDplz-EX2Qr3q5ieaJ3d8pXBA-DyZB5FSQWx1RHUBXECE7CFGGKORHYwNrrJnvh8P57TlrdfYFNvzmPgoUJFGl7WITIKG7saB3nhdY2j9MdQ4j1a1lH-QuK6p_Pz1fYYJVHQEmYRhMWOXExh675j7k3xB4NYRbPnpKFjinayfkWNq7aZg5dfX0Pv_ZjhO9crZnpqAbfATL5DxG0zomMtY4KZqma3qKLq3MXpijXqD4vshMheoo90IcTKOUkopcP7RFES-R3TXb-R_JtNUQ-Uw-Wc41t03ySkvM4U8nuPX_XZ3nzc6fLlHtRKC0dw5Bm7cELv7Nb1YgSVIAqJveQ_QtzSwfbJo9-wXDgjv13jA24l34IPbieVfXJ2LIExKVuptVyfKy4G8FndRlMRbhhsAeQuHw6l3dmSxD8VOVfCTa3YPCFyQ66AI_B2ALHRwbdibkxI_DBhuH2WDZxHD8jPhKK0GrcPniIbIR0QwsZ7NBNGBQNGD4c3nf0xeYQQTr8VzteRhEpz2ERXiGboqslL10qTch8s7pz_mu5Xqty2Izs7Xm6vowIKAEYA=s96-c and it will result in a too long file name.

Example code:

$path = download_url('https://lh3.googleusercontent.com/a-/AOh14Gglfqpi2Kz6aFTysWWgDnP2PszwkmL55tl4QNSX62jNTt-GK7ERhWuIT9AehHIzIlTdxBrNUUeWLwGyZeqsM3W300OX8xDy6lOmUMIChjOUMmfM1qHUKRbpZmElOXyT4DNLJiixrPuwkAH24sy5cQLtp8YPhdKR1SrErcXzFLjO1EQ2JvgLFvihaL92ddDERbdFVziBgsl9R0VDplz-EX2Qr3q5ieaJ3d8pXBA-DyZB5FSQWx1RHUBXECE7CFGGKORHYwNrrJnvh8P57TlrdfYFNvzmPgoUJFGl7WITIKG7saB3nhdY2j9MdQ4j1a1lH-QuK6p_Pz1fYYJVHQEmYRhMWOXExh675j7k3xB4NYRbPnpKFjinayfkWNq7aZg5dfX0Pv_ZjhO9crZnpqAbfATL5DxG0zomMtY4KZqma3qKLq3MXpijXqD4vshMheoo90IcTKOUkopcP7RFES-R3TXb-R_JtNUQ-Uw-Wc41t03ySkvM4U8nuPX_XZ3nzc6fLlHtRKC0dw5Bm7cELv7Nb1YgSVIAqJveQ_QtzSwfbJo9-wXDgjv13jA24l34IPbieVfXJ2LIExKVuptVyfKy4G8FndRlMRbhhsAeQuHw6l3dmSxD8VOVfCTa3YPCFyQ66AI_B2ALHRwbdibkxI_DBhuH2WDZxHD8jPhKK0GrcPniIbIR0QwsZ7NBNGBQNGD4c3nf0xeYQQTr8VzteRhEpz2ERXiGboqslL10qTch8s7pz_mu5Xqty2Izs7Xm6vowIKAEYA=s96-c');

Suggested changes:

  • in the download_url function, generate temporary file with empty argument, which creates a random filename: $tmpfname = wp_tempnam( );
  • in the wp_tempnam function limit the length of the input filename:
    function wp_tempnam( $filename = '', $dir = '' ) {
        if ( empty( $dir ) ) {
            $dir = get_temp_dir();
        }
     
        if ( empty( $filename ) || in_array( $filename, array( '.', '/', '\\' ), true ) ) {
            $filename = uniqid();
        }
     
        // Use the basename of the given file without the extension as the name for the temporary directory.
        $temp_filename = basename( $filename );
        $temp_filename = preg_replace( '|\.[^.]*$|', '', $temp_filename );
     
        // If the folder is falsey, use its parent directory name instead.
        if ( ! $temp_filename ) {
            return wp_tempnam( dirname( $filename ), $dir );
        }
    
        $temp_filename  = substr( $temp_filename, 0, 8 );
     
        // Suffix some random data to avoid filename conflicts.
        $temp_filename .= '-' . wp_generate_password( 6, false );
        $temp_filename .= '.tmp';
        $temp_filename  = $dir . wp_unique_filename( $dir, $temp_filename );
     
        $fp = @fopen( $temp_filename, 'x' );
        if ( ! $fp && is_writable( $dir ) && file_exists( $temp_filename ) ) {
            return wp_tempnam( $filename, $dir );
        }
        if ( $fp ) {
            fclose( $fp );
        }
     
        return $temp_filename;
    }
    

Change History (2)

#1 @desrosj
16 months ago

  • Component changed from General to Filesystem API
  • Keywords reporter-feedback added

Hey there @nextendweb!

Apologies that this took such a long time to receive a response.

It has been a while. Can you confirm that this is still an issue in the latest version of WordPress (currently 6.3)? If so, could you provide a bit more detail, such as the filesystem type you are seeing the problem with?

#2 @costdev
15 months ago

  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed

This appears to be a duplicate of #35755, which added handling in wp_tempnam() to ensure the generated filename does not exceed the typical limit on filesystems in [56186].

Note: See TracTickets for help on using tickets.