0

I am sanitizing uploaded SVG files with wp_handle_upload_prefilter, example:

// Example code
add_filter( 'wp_handle_upload_prefilter', function($file) {
    if ( $file['type'] === 'image/svg+xml' ) {
        $this->sanitize( $file['tmp_name'] );
    }
} );

It works fine for files uploaded through the Media Library, however, if the file is uploaded programatically, it doesn't go through the filter.

The reason I want to programatically upload an image is for testing purposes. I am uploading the file with wp_upload_bits function:

$upload = wp_upload_bits( 'xss.svg', null, file_get_contents( $this->svg_path ) );
$uploaded_svg_contents = file_get_contents( $upload['file'] );

$this->assertFalse( $upload['error'] );
$this->assertNotContains( '<script', $uploaded_svg_contents );

How can I upload a media file programatically, that goes through the wp_handle_upload_prefilter filter?

  • there's a plugin to auto-sanitize SVGs, additionally, SVGs aren't always image/svg+xml, they can be text/xml or image/svg and a few others. Also, why use wp_upload_bits? There are much higher level functions for sideloading files into attachments taht take all the work out of it – Tom J Nowell Apr 2 at 13:38
  • Hi @TomJNowell, this approach was taken from "Safe SVG" plugin, same author from this package packagist.org/packages/enshrined/svg-sanitize. I'm trying to get only the sanitization process without adding third-party plugins – Lucas Bustamante Apr 2 at 14:06
  • image/svg+xml is the mime specified in the upload_mimes filter: add_filter( 'upload_mimes', function($mimes) { $mimes['svg'] = 'image/svg+xml'; return $mimes } – Lucas Bustamante Apr 2 at 14:13
  • hmmm why? If you're copying the code it's still going to be just as fast/slow wether it's in a plugin or your themes functions.php. I've reviewed that plugins code myself, it's already quite lean and fast – Tom J Nowell Apr 2 at 14:22
  • @TomJNowell there was already a class to add support to SVG, and it does some things specific to our projects. Since I just needed to add sanitization to it, I thought a third-party plugin would be a little overhead. But yes, using a plugin is a great solution, too, I will study this SVG Support class and see if I can deprecate it in favor of a plugin maintained by a third-party – Lucas Bustamante Apr 2 at 14:29
0

I eventually got this. Solution was to use wp_handle_upload() function. Kinda obvious, when I come to think about it...

function handle_upload( string $path ): array {
    $filename        = basename( $path );
    $random_filename = rand( 0, 1000 ) . $filename;
    $tmp_path        = str_replace( $filename, $random_filename, $path );

    /** Create a temporary copy of the original file, since it will be moved during the upload process */
    copy( $path, $tmp_path );

    if ( file_exists( $tmp_path ) ) {
        $_files_mimic = [
            'name'     => $random_filename,
            'type'     => 'image/svg+xml',
            'tmp_name' => $tmp_path,
            'error'    => 0,
            'size'     => filesize( $tmp_path ),
        ];

        return wp_handle_upload( $_files_mimic, [
            'action'    => 'test_svg_upload',
            'test_form' => false,
        ] );
    } else {
        throw new RuntimeException( 'Could not copy test file from ' . $path . ' to ' . $tmp_path );
    }
}

Usage:

$upload_response = handle_upload('path/to/my/image.jpg');

Now if you debug $upload_response['file'], you should have your media processed by wp_handle_upload_filter, so you can test it or something.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.