Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/blocksy-companion-pro/framework/features/svg.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
3
+
namespace Blocksy;
4
+
5
+
class SvgHandling {
6
+
public function __construct() {
7
+
add_filter(
8
+
'wp_handle_upload_prefilter',
9
+
function ($file) {
10
+
$extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
11
+
12
+
if ('svg' !== $extension) {
13
+
return $file;
14
+
}
15
+
16
+
if (! apply_filters('blocksy:svg:should_sanitize', true)) {
17
+
return $file;
18
+
}
19
+
20
+
$svg_content = file_get_contents($file['tmp_name']);
21
+
22
+
$trimmed_content = trim($svg_content);
23
+
24
+
if (
25
+
strpos($trimmed_content, '<?xml') !== 0
26
+
&&
27
+
strpos($trimmed_content, '<svg') !== 0
28
+
) {
29
+
$file['error'] = __('This file does not appear to be a valid SVG file.', 'blocksy-companion');
30
+
return $file;
31
+
}
32
+
33
+
if (
34
+
stripos($svg_content, '<?php') !== false
35
+
||
36
+
stripos($svg_content, '<?=') !== false
37
+
) {
38
+
$file['error'] = __('SVG files cannot contain PHP code.', 'blocksy-companion');
39
+
return $file;
40
+
}
41
+
42
+
$sanitized_content = $this->cleanup_svg($svg_content);
43
+
44
+
file_put_contents($file['tmp_name'], $sanitized_content);
45
+
46
+
return $file;
47
+
}
48
+
);
49
+
50
+
add_filter(
51
+
'wp_get_attachment_metadata',
52
+
[$this, 'filter_get_attachment_metadata'],
53
+
10, 2
54
+
);
55
+
56
+
add_filter(
57
+
'wp_update_attachment_metadata',
58
+
[$this, 'filter_get_attachment_metadata'],
59
+
10, 2
60
+
);
61
+
62
+
add_filter(
63
+
'wp_get_attachment_image_src',
64
+
function ($image, $attachment_id, $size, $icon) {
65
+
if (! isset($attachment_id)) {
66
+
return $image;
67
+
}
68
+
69
+
$mime = get_post_mime_type($attachment_id);
70
+
71
+
if (
72
+
'image/svg+xml' === $mime
73
+
&&
74
+
$image[1] === 1
75
+
&&
76
+
$image[2] === 1
77
+
) {
78
+
$dimensions = $this->get_dimensions_for($attachment_id);
79
+
80
+
$image[2] = $dimensions['height'];
81
+
$image[1] = $dimensions['width'];
82
+
}
83
+
84
+
return $image;
85
+
},
86
+
10, 4
87
+
);
88
+
89
+
$should_add_filter = true;
90
+
91
+
// Avoid adding the filter during image cropping to prevent issues with SVGs.
92
+
// WP can't locate editor for SVGs so it throws an error.
93
+
if (
94
+
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
95
+
isset($_REQUEST['action'])
96
+
&&
97
+
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
98
+
$_REQUEST['action'] === 'crop-image'
99
+
) {
100
+
$should_add_filter = false;
101
+
}
102
+
103
+
if ($should_add_filter) {
104
+
add_filter('upload_mimes', [$this, 'upload_mimes']);
105
+
add_filter('wp_check_filetype_and_ext', [$this, 'wp_check_filetype_and_ext'], 75, 4);
106
+
}
107
+
}
108
+
109
+
public function wp_check_filetype_and_ext($data = null, $file = null, $filename = null, $mimes = null) {
110
+
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
111
+
112
+
// Only accept files with .svg as the final extension
113
+
// Reject files like test.svg.php, test.svg.jpg, etc.
114
+
if ($extension === 'svg') {
115
+
$data['type'] = 'image/svg+xml';
116
+
$data['ext'] = 'svg';
117
+
}
118
+
119
+
return $data;
120
+
}
121
+
122
+
public function upload_mimes($mimes) {
123
+
$mimes['svg'] = 'image/svg+xml';
124
+
return $mimes;
125
+
}
126
+
127
+
public function filter_get_attachment_metadata($data, $attachment_id) {
128
+
$mime = get_post_mime_type($attachment_id);
129
+
130
+
if (
131
+
'image/svg+xml' === $mime
132
+
&&
133
+
is_array($data)
134
+
&&
135
+
(
136
+
! isset($data['width'])
137
+
||
138
+
! isset($data['height'])
139
+
)
140
+
) {
141
+
$dimensions = $this->get_dimensions_for($attachment_id);
142
+
143
+
$data['width'] = $dimensions['width'];
144
+
$data['height'] = $dimensions['height'];
145
+
}
146
+
147
+
return $data;
148
+
}
149
+
150
+
public function get_dimensions_for($attachment_id) {
151
+
$height = 100;
152
+
$width = 100;
153
+
154
+
$maybe_file = get_attached_file($attachment_id);
155
+
156
+
if ($maybe_file) {
157
+
$dimensions = $this->svg_dimensions($maybe_file);
158
+
159
+
if ($dimensions) {
160
+
$height = round($dimensions['height']);
161
+
$width = round($dimensions['width']);
162
+
}
163
+
}
164
+
165
+
return [
166
+
'height' => $height,
167
+
'width' => $width
168
+
];
169
+
}
170
+
171
+
public function svg_dimensions($svg) {
172
+
if (
173
+
! preg_match('/.svg$/', $svg)
174
+
||
175
+
! file_exists($svg)
176
+
) {
177
+
return null;
178
+
}
179
+
180
+
$svg = file_get_contents($svg);
181
+
182
+
$attributes = new \stdClass();
183
+
184
+
if ($svg && function_exists('simplexml_load_string')) {
185
+
$svg = @simplexml_load_string($svg);
186
+
187
+
if ($svg) {
188
+
foreach ($svg->attributes() as $key => $value) {
189
+
$attributes->{$key} = strval($value);
190
+
}
191
+
}
192
+
}
193
+
194
+
if (
195
+
! isset($attributes->width)
196
+
&&
197
+
$svg
198
+
&&
199
+
function_exists('xml_parser_create')
200
+
) {
201
+
$xml = xml_parser_create('UTF-8');
202
+
203
+
$svgData = new \stdClass();
204
+
205
+
xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, false);
206
+
xml_set_element_handler(
207
+
$xml,
208
+
function ($parser, $name, $attrs) use (&$svgData) {
209
+
if ($name === 'SVG') {
210
+
if (isset($attrs['WIDTH'])) {
211
+
$attrs['width'] = $attrs['WIDTH'];
212
+
}
213
+
214
+
if (isset($attrs['HEIGHT'])) {
215
+
$attrs['height'] = $attrs['HEIGHT'];
216
+
}
217
+
218
+
if (isset($attrs['VIEWBOX'])) {
219
+
$attrs['viewBox'] = $attrs['VIEWBOX'];
220
+
}
221
+
222
+
foreach ($attrs as $key => $value) {
223
+
$svgData->{$key} = $value;
224
+
}
225
+
}
226
+
},
227
+
function ($parser, $tag) {
228
+
}
229
+
);
230
+
231
+
if (xml_parse($xml, $svg, true)) {
232
+
$attributes = $svgData;
233
+
}
234
+
235
+
xml_parser_free($xml);
236
+
}
237
+
238
+
$width = 0;
239
+
$height = 0;
240
+
241
+
if (empty($attributes)) {
242
+
return false;
243
+
}
244
+
245
+
if (
246
+
isset($attributes->width, $attributes->height)
247
+
&&
248
+
is_numeric($attributes->width)
249
+
&&
250
+
is_numeric($attributes->height)
251
+
) {
252
+
$width = floatval($attributes->width);
253
+
$height = floatval($attributes->height);
254
+
} elseif (isset($attributes->viewBox)) {
255
+
$sizes = explode(' ', $attributes->viewBox);
256
+
257
+
if (isset($sizes[2], $sizes[3])) {
258
+
$width = floatval($sizes[2]);
259
+
$height = floatval($sizes[3]);
260
+
}
261
+
} else {
262
+
return false;
263
+
}
264
+
265
+
return [
266
+
'width' => $width,
267
+
'height' => $height,
268
+
'orientation' => ($width > $height) ? 'landscape' : 'portrait'
269
+
];
270
+
}
271
+
272
+
public function cleanup_svg($content) {
273
+
$base_path = BLOCKSY_PATH . 'vendor/svg-sanitizer/src';
274
+
275
+
require_once($base_path . '/data/AttributeInterface.php');
276
+
require_once($base_path . '/data/TagInterface.php');
277
+
require_once($base_path . '/data/AllowedAttributes.php');
278
+
require_once($base_path . '/data/AllowedTags.php');
279
+
require_once($base_path . '/data/XPath.php');
280
+
require_once($base_path . '/ElementReference/Resolver.php');
281
+
require_once($base_path . '/ElementReference/Subject.php');
282
+
require_once($base_path . '/ElementReference/Usage.php');
283
+
require_once($base_path . '/Exceptions/NestingException.php');
284
+
require_once($base_path . '/Helper.php');
285
+
require_once($base_path . '/Sanitizer.php');
286
+
287
+
$sanitizer = new \blocksy\enshrined\svgSanitize\Sanitizer();
288
+
289
+
// Remove <?xml tag from the SVG content to avoid html5
290
+
// validation issues when embedding SVGs inline.
291
+
$sanitizer->removeXMLTag(true);
292
+
293
+
return $sanitizer->sanitize($content);
294
+
}
295
+
}
296
+
297
+