Safe SVG - Version 1.4.0

Version Description

  • Added ability to preview SVG on both grid and list view in the wp-admin media area
  • Updated underlying library version
Download this release

Release Info

Developer enshrined
Plugin Icon 128x128 Safe SVG
Version 1.4.0
Comparing to
See all releases

Code changes from version 1.3.2 to 1.4.0

Files changed (3) hide show
  1. licence.txt +1 -1
  2. readme.txt +25 -15
  3. safe-svg.php +92 -3
licence.txt CHANGED
@@ -1,4 +1,4 @@
1
- Safe SVG - Upload and sanitize SVGs within Wordpress
2
 
3
  Copyright 2015 Daryll Doyle
4
 
1
+ Safe SVG - Upload and sanitize SVGs within WordPress
2
 
3
  Copyright 2015 Daryll Doyle
4
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://enshrined.co.uk
4
  Tags: svg, sanitize, uploads, sanitise, security, svg upload
5
  Requires at least: 4.0
6
  Tested up to: 4.7.2
7
- Stable tag: 1.3.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -24,25 +24,35 @@ Install through the WordPress directory or download, unzip and upload the files
24
 
25
  == Changelog ==
26
 
27
- = 1.0.0 =
28
- * Initial Release
 
29
 
30
- = 1.1.0 =
31
- * Added i18n
32
- * Added da, de ,en, es, fr, nl and ru translations
33
- * Fixed an issue with filename not being pulled over on failed uploads
34
 
35
- = 1.1.1 =
36
- * Fixed an issue with empty svg elements self-closing
37
 
38
- = 1.2.0 =
39
- * Added support for camel case attributes such as viewBox
 
 
 
40
 
41
  = 1.3.0 =
42
  * Minify SVGs after cleaning so they can be loaded correctly through file_get_contents
43
 
44
- = 1.3.1 =
45
- * Updated underlying library version
46
 
47
- = 1.3.2 =
48
- * Fix for the mime type issue in 4.7.1. Mad props to @lewiscowles
 
 
 
 
 
 
 
 
4
  Tags: svg, sanitize, uploads, sanitise, security, svg upload
5
  Requires at least: 4.0
6
  Tested up to: 4.7.2
7
+ Stable tag: 1.4.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
24
 
25
  == Changelog ==
26
 
27
+ = 1.4.0 =
28
+ * Added ability to preview SVG on both grid and list view in the wp-admin media area
29
+ * Updated underlying library version
30
 
31
+ = 1.3.4 =
32
+ * A fix for SVGZ uploads failing and not sanitising correctly
 
 
33
 
34
+ = 1.3.3 =
35
+ * Allow SVGZ uploads
36
 
37
+ = 1.3.2 =
38
+ * Fix for the mime type issue in 4.7.1. Mad props to @lewiscowles
39
+
40
+ = 1.3.1 =
41
+ * Updated underlying library version
42
 
43
  = 1.3.0 =
44
  * Minify SVGs after cleaning so they can be loaded correctly through file_get_contents
45
 
46
+ = 1.2.0 =
47
+ * Added support for camel case attributes such as viewBox
48
 
49
+ = 1.1.1 =
50
+ * Fixed an issue with empty svg elements self-closing
51
+
52
+ = 1.1.0 =
53
+ * Added i18n
54
+ * Added da, de ,en, es, fr, nl and ru translations
55
+ * Fixed an issue with filename not being pulled over on failed uploads
56
+
57
+ = 1.0.0 =
58
+ * Initial Release
safe-svg.php CHANGED
@@ -2,8 +2,8 @@
2
  /*
3
  Plugin Name: Safe SVG
4
  Plugin URI: https://wordpress.org/plugins/safe-svg/
5
- Description: Allows SVG uploads into Wordpress and sanitizes the SVG before saving it
6
- Version: 1.3.2
7
  Author: Daryll Doyle
8
  Author URI: http://enshrined.co.uk
9
  Text Domain: safe-svg
@@ -38,6 +38,8 @@ if ( ! class_exists( 'safe_svg' ) ) {
38
  add_filter( 'upload_mimes', array( $this, 'allow_svg' ) );
39
  add_filter( 'wp_handle_upload_prefilter', array( $this, 'check_for_svg' ) );
40
  add_filter( 'wp_check_filetype_and_ext', array( $this, 'fix_mime_type_svg' ), 75, 4 );
 
 
41
  }
42
 
43
  /**
@@ -49,6 +51,7 @@ if ( ! class_exists( 'safe_svg' ) ) {
49
  */
50
  public function allow_svg( $mimes ) {
51
  $mimes['svg'] = 'image/svg+xml';
 
52
 
53
  return $mimes;
54
  }
@@ -73,7 +76,10 @@ if ( ! class_exists( 'safe_svg' ) ) {
73
  if ( $ext === 'svg' ) {
74
  $data['type'] = 'image/svg+xml';
75
  $data['ext'] = 'svg';
76
- }
 
 
 
77
 
78
  return $data;
79
  }
@@ -107,17 +113,100 @@ if ( ! class_exists( 'safe_svg' ) ) {
107
  protected function sanitize( $file ) {
108
  $dirty = file_get_contents( $file );
109
 
 
 
 
 
 
 
 
 
 
 
110
  $clean = $this->sanitizer->sanitize( $dirty );
111
 
112
  if ( $clean === false ) {
113
  return false;
114
  }
115
 
 
 
 
 
 
116
  file_put_contents( $file, $clean );
117
 
118
  return true;
119
  }
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  }
122
  }
123
 
2
  /*
3
  Plugin Name: Safe SVG
4
  Plugin URI: https://wordpress.org/plugins/safe-svg/
5
+ Description: Allows SVG uploads into WordPress and sanitizes the SVG before saving it
6
+ Version: 1.4.0
7
  Author: Daryll Doyle
8
  Author URI: http://enshrined.co.uk
9
  Text Domain: safe-svg
38
  add_filter( 'upload_mimes', array( $this, 'allow_svg' ) );
39
  add_filter( 'wp_handle_upload_prefilter', array( $this, 'check_for_svg' ) );
40
  add_filter( 'wp_check_filetype_and_ext', array( $this, 'fix_mime_type_svg' ), 75, 4 );
41
+ add_filter( 'wp_prepare_attachment_for_js', array( $this, 'fix_admin_preview' ), 10, 3 );
42
+ add_filter( 'wp_get_attachment_image_src', array( $this, 'one_pixel_fix' ), 10, 4 );
43
  }
44
 
45
  /**
51
  */
52
  public function allow_svg( $mimes ) {
53
  $mimes['svg'] = 'image/svg+xml';
54
+ $mimes['svgz'] = 'image/svg+xml';
55
 
56
  return $mimes;
57
  }
76
  if ( $ext === 'svg' ) {
77
  $data['type'] = 'image/svg+xml';
78
  $data['ext'] = 'svg';
79
+ } elseif ( $ext === 'svgz' ) {
80
+ $data['type'] = 'image/svg+xml';
81
+ $data['ext'] = 'svgz';
82
+ }
83
 
84
  return $data;
85
  }
113
  protected function sanitize( $file ) {
114
  $dirty = file_get_contents( $file );
115
 
116
+ // Is the SVG gzipped? If so we try and decode the string
117
+ if ( $is_zipped = $this->is_gzipped( $dirty ) ) {
118
+ $dirty = gzdecode( $dirty );
119
+
120
+ // If decoding fails, bail as we're not secure
121
+ if ( $dirty === false ) {
122
+ return false;
123
+ }
124
+ }
125
+
126
  $clean = $this->sanitizer->sanitize( $dirty );
127
 
128
  if ( $clean === false ) {
129
  return false;
130
  }
131
 
132
+ // If we were gzipped, we need to re-zip
133
+ if ( $is_zipped ) {
134
+ $clean = gzencode( $clean );
135
+ }
136
+
137
  file_put_contents( $file, $clean );
138
 
139
  return true;
140
  }
141
 
142
+ /**
143
+ * Check if the contents are gzipped
144
+ * @see http://www.gzip.org/zlib/rfc-gzip.html#member-format
145
+ *
146
+ * @param $contents
147
+ *
148
+ * @return bool
149
+ */
150
+ protected function is_gzipped( $contents ) {
151
+ return 0 === mb_strpos( $contents , "\x1f" . "\x8b" . "\x08" );
152
+ }
153
+
154
+ /**
155
+ * Filters the attachment data prepared for JavaScript to add the sizes array to the response
156
+ *
157
+ * @param array $response Array of prepared attachment data.
158
+ * @param int|object $attachment Attachment ID or object.
159
+ * @param array $meta Array of attachment meta data.
160
+ *
161
+ * @return array
162
+ */
163
+ public function fix_admin_preview( $response, $attachment, $meta ) {
164
+
165
+ if ( $response['mime'] == 'image/svg+xml' ) {
166
+ $possible_sizes = apply_filters( 'image_size_names_choose', array(
167
+ 'thumbnail' => __( 'Thumbnail' ),
168
+ 'medium' => __( 'Medium' ),
169
+ 'large' => __( 'Large' ),
170
+ 'full' => __( 'Full Size' ),
171
+ ) );
172
+
173
+ $sizes = array();
174
+
175
+ foreach ( $possible_sizes as $size ) {
176
+ $sizes[ $size ] = array(
177
+ 'height' => 2000,
178
+ 'width' => 2000,
179
+ 'url' => $response['url'],
180
+ 'orientation' => 'portrait',
181
+ );
182
+ }
183
+
184
+ $response['sizes'] = $sizes;
185
+ }
186
+
187
+ return $response;
188
+ }
189
+
190
+ /**
191
+ * Filters the image src result.
192
+ * Here we're gonna spoof the image size and set it to 100 width and height
193
+ *
194
+ * @param array|false $image Either array with src, width & height, icon src, or false.
195
+ * @param int $attachment_id Image attachment ID.
196
+ * @param string|array $size Size of image. Image size or array of width and height values
197
+ * (in that order). Default 'thumbnail'.
198
+ * @param bool $icon Whether the image should be treated as an icon. Default false.
199
+ *
200
+ * @return array
201
+ */
202
+ public function one_pixel_fix( $image, $attachment_id, $size, $icon ) {
203
+ if ( get_post_mime_type( $attachment_id ) == 'image/svg+xml' ) {
204
+ $image['1'] = 100;
205
+ $image['2'] = 100;
206
+ }
207
+
208
+ return $image;
209
+ }
210
  }
211
  }
212