[wp-trac] [WordPress Trac] #40795: If plugin zip file has very long name, windows systems can fail to upgrade

WordPress Trac noreply at wordpress.org
Wed May 17 23:17:54 UTC 2017


#40795: If plugin zip file has very long name, windows systems can fail to upgrade
--------------------------+-----------------------------
 Reporter:  rogerlos      |      Owner:
     Type:  defect (bug)  |     Status:  new
 Priority:  normal        |  Milestone:  Awaiting Review
Component:  Plugins       |    Version:  4.7.5
 Severity:  normal        |   Keywords:
  Focuses:                |
--------------------------+-----------------------------
 If a plugin upgrade zip file has an extremely long name and the plugin a
 deep directory structure, windows can fail to create directories and
 therefore the plugin upgrade will fail.

 I suggest WordPress have an upper limit on the working directory name that
 is well-shy of that limit--and realistically, even 32 characters might be
 plenty, as the upgrader only needs to avoid other plugins being upgraded
 at the same time.

 Windows has a 247-character limit to the total ''path'' name for
 directories, as said directory needs to be able to hold, at a minimum, an
 "8+3" file, and allow for a null byte or similar at the end of path + file
 (260 total characters).

 As an example, SearchWP fails to upgrade on my local system (WAMP running
 on top of Windows 10) because the downloaded zip filename is 142
 characters long ''sans'' extension (redacted in case this is a license
 key):

 {{{
 XXX0XXX0XxxxXXxxXXX0XxXxXxX0XXXxXxXxXXXxXxXxXXX0XXx
 0X0XxXXx0XxX0XXxxXXX0XXx0X0XxXXX0Xxx0XxX0XXXxXXX0XX
 XxXxx0xXXXXx0xXXXxxxxxXxxxX0XxXxX-0xxXXx.zip
 }}}

 Combine that with my wordpress location on disk:

 {{{
 C:/wamp/www/example/wp-content/upgrade/
 }}}

 And this directory cannot be created because the total path is 254
 characters long (including the hidden null):

 {{{
 C:/wamp/www/example/wp-content/upgrade/XXX0XXX0Xxxx
 XXxxXXX0XxXxXxX0XXXxXxXxXXXxXxXxXXX0XXx0X0XxXXx0XxX
 0XXxxXXX0XXx0X0XxXXX0Xxx0XxX0XXXxXXX0XXXxXxx0xXXXXx
 0xXXXxxxxxXxxxX0XxXxX-0xxXXx/searchwp/vendor/
 pdfparser/vendor/smalot/pdfparser/src/Smalot/PdfParser
 }}}

 I think that while this may be an outlier, it's a hard bug to chase for a
 vendor who may not have windows systems available...and even they do have
 such an environment available, the results returned by Apache when running
 WAMP (or in similar environments) does not reflect the actual cause of the
 error.

 Looking at the structure above as pretty much as edge-case as you are
 likely to get, even a truncate at 64 characters would have been more than
 adequate, while 32 characters would give quite a bit of room for
 flexibility.

 I believe that this could be affected by altering `wp_tempnam()` in
 `file.php`:

 {{{
 /**
  * Returns a filename of a Temporary unique file.
  * Please note that the calling function must unlink() this itself.
  *
  * The filename is based off the passed parameter or defaults to the
 current unix timestamp,
  * while the directory can either be passed as well, or by leaving it
 blank, default to a writable temporary directory.
  *
  * @since 2.6.0
  *
  * @param string $filename Optional. Filename to base the Unique file off.
 Default empty.
  * @param string $dir      Optional. Directory to store the file in.
 Default empty.
  * @return string a writable filename
  *
  * @since x.x.x
  * @param int|string $maxlen  Optional. Maximum length (excluding
 extension) of returned filename
  */
 function wp_tempnam( $filename = '', $dir = '', $maxlen = 32 ) {
     if ( empty( $dir ) ) {
         $dir = get_temp_dir();
     }

     if ( empty( $filename ) || '.' == $filename || '/' == $filename ||
 '\\' == $filename ) {
         $filename = time();
     }

     // 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 );

     // new: truncate the filename if longer than specified
     $max = intval( $maxlen ) > 0 ? intval( $maxlen ) - 6 : 32;
     $temp_filename = strlen( $temp_filename ) > $max ?
             substr( $temp_filename, 0, $max ) : $temp_filename;

     // ... remainder omitted for clarity

     return $temp_filename;
 }
 }}}

 An alternative would be to require plugin upgrade files to have filenames
 shorter than [insert recommendation here], though actually checking that
 would mean a similar chunk of code would need to be added elsewhere in WP.

 (Not sure exactly where the best place to document this for plugin
 authors, which could be done immediately.)

--
Ticket URL: <https://core.trac.wordpress.org/ticket/40795>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list