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

hook_file_validate()

Related topics

File

core/includes/file.inc, line 2125
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);

    // Entity declarations could be used to hide content from the checks below
    // or to consume excessive memory when expanded, so they are not allowed.
    if (!strlen($file_contents) || stripos($file_contents, '<!ENTITY') !== FALSE) {
      return array(t('Invalid SVG file.'));
    }

    // Parse the file exactly as it will be delivered to the browser. The
    // contents must not be modified (such as by decoding entities or changing
    // case) prior to parsing, as that could cause the parsed structure to
    // differ from what a browser renders, hiding dangerous content.
    $previous_use_errors = libxml_use_internal_errors(TRUE);
    libxml_clear_errors();
    $dom = new DOMDocument();
    $loaded = $dom->loadXML($file_contents, LIBXML_NONET);
    $libxml_errors = libxml_get_errors();
    libxml_clear_errors();
    libxml_use_internal_errors($previous_use_errors);

    if (!$loaded || !empty($libxml_errors) || !$dom->documentElement || ($dom->doctype && strlen((string) $dom->doctype->internalSubset))) {
      $errors[] = t('Invalid SVG file.');
    }
    elseif ($dom->documentElement->namespaceURI !== 'http://www.w3.org/2000/svg') {
      $errors[] = t('Invalid SVG namespace.');
    }
    elseif (_file_validate_svg_dangerous_content($dom)) {
      $errors[] = t('Dangerous content found.');
    }
  }

  return $errors;
}