Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion inc/class-main.php
Original file line number Diff line number Diff line change
Expand Up @@ -529,11 +529,29 @@ public function generate_svg_attachment_metadata( $metadata, $attachment_id ) {
}

$svg_path = get_attached_file( $attachment_id );

if ( empty( $svg_path ) || ! file_exists( $svg_path ) || ! is_readable( $svg_path ) ) {
return $metadata;
}

$filename = basename( $svg_path );

$svg = simplexml_load_file( $svg_path );
// Keep malformed SVG errors internal instead of emitting PHP warnings.
$previous_state = libxml_use_internal_errors( true );
$svg = simplexml_load_file( $svg_path );
libxml_clear_errors();
libxml_use_internal_errors( $previous_state );

if ( false === $svg ) {
return $metadata;
}

$attributes = $svg->attributes();

if ( ! isset( $attributes->width, $attributes->height ) ) {
return $metadata;
}

// Update metadata with SVG dimensions.
$metadata['width'] = intval( (string) $attributes->width );
$metadata['height'] = intval( (string) $attributes->height );
Expand Down
116 changes: 116 additions & 0 deletions tests/test-svg-upload.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,120 @@ public function test_used_css_properties_returns_default_when_input_is_not_array
$this->assertContains( 'border-radius', $result );
$this->assertContains( 'transform', $result );
}

/**
* Create an SVG attachment post for the supplied file path.
*
* @param string $file Attached file path to store, may be empty.
* @return int
*/
private function create_svg_attachment( $file ) {
$attachment_id = $this->factory()->attachment->create_object(
array(
'file' => $file,
'post_mime_type' => 'image/svg+xml',
)
);

return $attachment_id;
}

/**
* A missing SVG file must not fatal, and metadata is returned untouched.
*/
public function test_generate_svg_attachment_metadata_with_missing_file() {
$main = new ThemeIsle\GutenbergBlocks\Main();
$attachment_id = $this->create_svg_attachment( '/does/not/exist/missing.svg' );
$metadata = array( 'sizes' => array() );

$result = $main->generate_svg_attachment_metadata( $metadata, $attachment_id );

$this->assertSame( $metadata, $result );

wp_delete_attachment( $attachment_id, true );
}

/**
* get_attached_file() returning false must not fatal.
*/
public function test_generate_svg_attachment_metadata_when_attached_file_is_false() {
$main = new ThemeIsle\GutenbergBlocks\Main();
$attachment_id = $this->create_svg_attachment( '' );
$metadata = array( 'sizes' => array() );

$force_false = '__return_false';
add_filter( 'get_attached_file', $force_false );

$result = $main->generate_svg_attachment_metadata( $metadata, $attachment_id );

remove_filter( 'get_attached_file', $force_false );

$this->assertSame( $metadata, $result );

wp_delete_attachment( $attachment_id, true );
}

/**
* A file that is not valid XML must not fatal.
*/
public function test_generate_svg_attachment_metadata_with_malformed_svg() {
$main = new ThemeIsle\GutenbergBlocks\Main();
$svg_path = wp_tempnam( 'broken.svg' );
file_put_contents( $svg_path, '<svg width="10" height="10">' );

$attachment_id = $this->create_svg_attachment( $svg_path );
$metadata = array( 'sizes' => array() );

$result = $main->generate_svg_attachment_metadata( $metadata, $attachment_id );

$this->assertSame( $metadata, $result );

wp_delete_attachment( $attachment_id, true );
if ( file_exists( $svg_path ) ) {
unlink( $svg_path );
}
}

/**
* A valid SVG still gets its dimensions filled in.
*/
public function test_generate_svg_attachment_metadata_with_valid_svg() {
$main = new ThemeIsle\GutenbergBlocks\Main();
$svg_path = wp_tempnam( 'valid.svg' );
file_put_contents( $svg_path, '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="42"></svg>' );

$attachment_id = $this->create_svg_attachment( $svg_path );

$result = $main->generate_svg_attachment_metadata( array( 'sizes' => array() ), $attachment_id );

$this->assertSame( 24, $result['width'] );
$this->assertSame( 42, $result['height'] );
$this->assertSame( basename( $svg_path ), $result['file'] );

wp_delete_attachment( $attachment_id, true );
if ( file_exists( $svg_path ) ) {
unlink( $svg_path );
}
}

/**
* An SVG without width/height attributes must not produce zeroed dimensions.
*/
public function test_generate_svg_attachment_metadata_without_dimension_attributes() {
$main = new ThemeIsle\GutenbergBlocks\Main();
$svg_path = wp_tempnam( 'no-dimensions.svg' );
file_put_contents( $svg_path, '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 42"></svg>' );

$attachment_id = $this->create_svg_attachment( $svg_path );
$metadata = array( 'sizes' => array() );

$result = $main->generate_svg_attachment_metadata( $metadata, $attachment_id );

$this->assertSame( $metadata, $result );

wp_delete_attachment( $attachment_id, true );
if ( file_exists( $svg_path ) ) {
unlink( $svg_path );
}
}
}
Loading