1 file.inc | file_validate_svg(File $file) |
Validate uploaded SVG files.
Parameters
File $file: A file entity.
Return value
array: If the file is an SVG and is either not valid or contains dangerous content, the array will contain an error message.
See also
Related topics
File
- core/
includes/ file.inc, line 2036 - API for handling file uploads and server file management.
Code
function file_validate_svg(File $file) {
$errors = array();
if ($file->filemime == 'image/svg+xml') {
$file_contents = file_get_contents($file->uri);
$file_contents = preg_replace('/<!DOCTYPE[^>]*>/i', '', $file_contents);
$file_contents = html_entity_decode($file_contents);
$file_contents = strtolower($file_contents);
libxml_use_internal_errors(TRUE);
$xml = simplexml_load_string($file_contents);
$errors = libxml_get_errors();
if (!$xml || !empty($errors)) {
return array(t('Invalid SVG file.'));
}
else {
$errors = array();
$namespaces = $xml->getNamespaces();
if (!in_array('http://www.w3.org/2000/svg', $namespaces)) {
$errors[] = t('Invalid SVG namespace.');
}
$search_patterns = array(
// @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element
'//svg:foreignobject',
'//svg:script',
'//html:iframe',
// @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute
'//@*[starts-with(name(), "on")]',
'//svg:a[starts-with(normalize-space(@href), "javascript:")]',
'//svg:a[starts-with(normalize-space(@xlink:href), "javascript:")]',
'//svg:a[starts-with(normalize-space(@href), "data:")]',
'//svg:a[starts-with(normalize-space(@xlink:href), "data:")]',
);
$xml->registerXPathNamespace('svg', 'http://www.w3.org/2000/svg');
$xml->registerXPathNamespace('html', 'http://www.w3.org/1999/xhtml');
foreach ($search_patterns as $search_pattern) {
$found = $xml->xpath($search_pattern);
if (!empty($found)) {
$errors[] = t('Dangerous content found.');
break;
}
}
}
libxml_clear_errors();
libxml_use_internal_errors(FALSE);
}
return $errors;
}