/* * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.yangtools.util.xml; import com.google.common.annotations.Beta; import javax.annotation.Nonnull; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; /** * Set of utility methods for instantiating parser that deal with untrusted XML sources. * * @author Robert Varga */ @Beta public final class UntrustedXML { private static final DocumentBuilderFactory DBF; static { final DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); f.setCoalescing(true); f.setExpandEntityReferences(false); f.setIgnoringElementContentWhitespace(true); f.setIgnoringComments(true); f.setNamespaceAware(true); f.setXIncludeAware(false); try { f.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); f.setFeature("http://xml.org/sax/features/external-general-entities", false); f.setFeature("http://xml.org/sax/features/external-parameter-entities", false); } catch (final ParserConfigurationException e) { throw new ExceptionInInitializerError(e); } DBF = f; } private static final SAXParserFactory SPF; static { final SAXParserFactory f = SAXParserFactory.newInstance(); f.setNamespaceAware(true); f.setXIncludeAware(false); try { f.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); f.setFeature("http://xml.org/sax/features/external-general-entities", false); f.setFeature("http://xml.org/sax/features/external-parameter-entities", false); } catch (final Exception e) { throw new ExceptionInInitializerError(e); } SPF = f; } /** * Create a new {@link DocumentBuilder} for dealing with untrusted XML data. This method is equivalent to * {@link DocumentBuilderFactory#newDocumentBuilder()}, except it does not throw a checked exception. * * @return A new DocumentBuilder * @throws UnsupportedOperationException if the runtime fails to instantiate a good enough builder */ public static @Nonnull DocumentBuilder newDocumentBuilder() { try { return DBF.newDocumentBuilder(); } catch (ParserConfigurationException e) { throw new UnsupportedOperationException("Failed to instantiate a DocumentBuilder", e); } } /** * Create a new {@link SAXParser} for dealing with untrusted XML data. This method is equivalent to * {@link SAXParserFactory#newSAXParser()}, except it does not throw a checked exception. * * @return A new SAXParser * @throws UnsupportedOperationException if the runtime fails to instantiate a good enough builder */ public static @Nonnull SAXParser newSAXParser() { try { return SPF.newSAXParser(); } catch (ParserConfigurationException | SAXException e) { throw new UnsupportedOperationException("Failed to instantiate a SAXParser", e); } } }