Subscribe to
Posts
Comments
NSLog(); Header Image

Fixing WordPress 2.1.1’s Broken XML-RPC Image Uploading

In WordPress 2.1, I encountered a few problems uploading images. One of the problems was solved with a plugin that disables the creation of a thumbnail. Two others are solved with a nightly cron job. The last problem - renaming of images and ignoring of specified paths - was solved by commenting out $name = sanitize_file_name( $data['name'] ); in xmlrpc.php.

This fix no longer works in WordPress 2.1.1. In fact, commenting out this line of code throws an error at you: could not write file.

Thus, WordPress 2.1.1 again breaks image uploading via XML-RPC (I use ecto). Un-commenting the line allows images to upload, yet again in the wrong folder and with - replacing _.

Request with URL:
http://nslog.com/xmlrpc.php
and data:
<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>metaWeblog.newMediaObject</methodName>
<params>
  <param>
    <value><string>1</string></value>
  </param>
  <param>
    <value><string>username</string></value>
  </param>
  <param>
    <value><string>**********</string></value>
  </param>
  <param>
  <value><struct>
  <member>
    <name>bits</name>
    <value>REMOVED</value>
  </member>
  <member>
    <name>name</name>
    <value><string>photos/image_name.jpg</string></value>
  </member>
  <member>
    <name>type</name>
    <value><string>image/jpeg</string></value>
  </member>
  </struct></value>
  </param>
</params>
</methodCall>
Response:
<?xml version="1.0"?>
<methodResponse>
  <fault>
    <value>
      <struct>
        <member>
          <name>faultCode</name>
          <value><int>500</int></value>
        </member>
        <member>
          <name>faultString</name>
          <value><string>Could not write file </string></value>
        </member>
      </struct>
    </value>
  </fault>
</methodResponse>

The function, found in wp-includes/formatting.php is relatively simple:

function sanitize_file_name( $name ) { // Like sanitize_title, but with periods
    $name = strtolower( $name );
    $name = preg_replace('/&.+?;/', '', $name); // kill entities
    $name = str_replace( '_', '-', $name );
    $name = preg_replace('/[^a-z0-9\\s-.]/', '', $name);
    $name = preg_replace('/\\s+/', '-', $name);
    $name = preg_replace('|-+|', '-', $name);
    $name = trim($name, '-');
    return $name;
}

Removing the part that changes "_" into "-" is easy:

//  $name = str_replace( '_', '-', $name );

Removing the part that obliterates the "/" from our paths is not as easy, but through trial and error (if you can't read regular expressions), it can be found:

//  $name = preg_replace('/[^a-z0-9\\s-.]/', '', $name);

This solves the problem (and lets you upload images to the proper folders), but at the cost of sacrificing an entire other series of "fixes." This line is responsible for the removal of characters not in the ranges a-z, 0-9, whitespace, ".", and "-" characters. Additionally, PHP seems to let the rogue "-" towards the end of the expression slide. In this form, normally the "-" would be a range operator, but with no range, PHP must allow its presence as a character. Normally it would need escaped, as in:

$name = preg_replace('/[^a-z0-9\\s\\-.]/', '', $name);

It would be much wiser to simply add the "/" character to the allowed list. That's simply done:

$name = preg_replace('/[^a-z0-9\\s\\-.\\/_]/', '', $name);

This final solution cleans up the rogue "-" and adds support for both "/" and "_" as valid characters.

In other words, to fix image uploading with an XML-RPC client in WordPress 2.1.1, it was necessary for me to make the following change to wp-includes/formatting.php:

function sanitize_file_name( $name ) { // Like sanitize_title, but with periods
    $name = strtolower( $name );
    $name = preg_replace('/&.+?;/', '', $name); // kill entities
//  $name = str_replace( '_', '-', $name );
    $name = preg_replace('/[^a-z0-9\\s\\-.\\/_]/', '', $name);
    $name = preg_replace('/\\s+/', '-', $name);
    $name = preg_replace('|-+|', '-', $name);
    $name = trim($name, '-');
    return $name;
}

6 Responses to "Fixing WordPress 2.1.1’s Broken XML-RPC Image Uploading"

  1. Interestingly, WordPress strips "\" characters. I have to put "\\" to get them to appear.

  2. I applied the patch to wp 2.1.2 and changed the image upload directory to /images in Options:Miscellaneous. Now images show up in wp/images. I want images out of WP directory in /images in server root, like it's always been. How do I get WP to stop putting images in it's own subdirectory?

  3. [quote comment="39841"]I applied the patch to wp 2.1.2 and changed the image upload directory to /images in Options:Miscellaneous. Now images show up in wp/images. I want images out of WP directory in /images in server root, like it's always been. How do I get WP to stop putting images in it's own subdirectory?[/quote]

    Dave, WordPress defaults to the directory in which WordPress is installed. Perhaps you could try setting your image uploads in the WP settings to "../images"? I don't have any installations of WordPress in a subdirectory, so my ability to test this is limited.

  4. I just realized I had written about how to fix this for WP 2.0.* but this doesn't work anymore with 2.1.*

    http://theprogressbar.com/archives/2006/11/installing_wordpress_from_scratch/

    Somehow in wp-includes/functions.php I need to set the default path to the server directory root by changing ABSPATH with document_root.

    Yes I do have WP installed in a subdirectory, yet another problem when it comes to upgrades.

  5. [...] overridden very little on this blog - just enough to "fix" broken image uploading - so I have to assume these are WordPress 2.2 bugs. I don't have the time right now to look into [...]

  6. [...] hacks I still have to make to the code: one adjusts the kses properties and the other "fixes" the uploading of files, though lately I've been using an AppleScript for the latter [...]