public static boolean isXMLWellFormed( InputStream is ) throws KettleException {
    boolean retval = false;
    try {
      SAXParserFactory factory = XMLParserFactoryProducer.createSecureSAXParserFactory();
      XMLTreeHandler handler = new XMLTreeHandler();

      // Parse the input.
      SAXParser saxParser = factory.newSAXParser();
      saxParser.parse( is, handler );
      retval = true;
    } catch ( Exception e ) {
      throw new KettleException( e );
    }
    return retval;
  }
@Test( expected = KettleException.class )
  public void exceptionIsThrownWhenParsingXmlWithBigAmountOfExternalEntities() throws KettleException {
    final String maliciousXml =
      "<?xml version=\"1.0\"?>\n"
        + "<!DOCTYPE lolz [\n"
        + " <!ENTITY lol \"lol\">\n"
        + " <!ELEMENT lolz (#PCDATA)>\n"
        + " <!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\n"
        + " <!ENTITY lol2 \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">\n"
        + " <!ENTITY lol3 \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\n"
        + " <!ENTITY lol4 \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\n"
        + " <!ENTITY lol5 \"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;\">\n"
        + " <!ENTITY lol6 \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\n"
        + " <!ENTITY lol7 \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\n"
        + " <!ENTITY lol8 \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\n"
        + " <!ENTITY lol9 \"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\n"
        + "]>\n"
        + "<lolz>&lol9;</lolz>";

    XMLCheck.isXMLWellFormed( new ByteArrayInputStream( maliciousXml.getBytes() ) );
  }