parse xml only if xml parseable in invoiceimporter (affecting metrics)
This commit is contained in:
@@ -12,6 +12,11 @@ import org.dom4j.io.XMLWriter;
|
||||
import org.mustangproject.ZUGFeRD.ZUGFeRDDateFormat;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
public class XMLTools extends XMLWriter {
|
||||
@Override
|
||||
public String escapeAttributeEntities(String s) {
|
||||
@@ -23,6 +28,30 @@ public class XMLTools extends XMLWriter {
|
||||
return super.escapeElementEntities(s);
|
||||
}
|
||||
|
||||
public static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
|
||||
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
//REDHAT
|
||||
//https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf
|
||||
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
||||
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
|
||||
|
||||
//OWASP
|
||||
//https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||
// Disable external DTDs as well
|
||||
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
|
||||
dbf.setXIncludeAware(false);
|
||||
dbf.setExpandEntityReferences(false);
|
||||
dbf.setNamespaceAware(true);
|
||||
return dbf.newDocumentBuilder();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String nDigitFormat(BigDecimal value, int scale) {
|
||||
/*
|
||||
* I needed 123.45, locale independent.I tried
|
||||
|
||||
@@ -19,6 +19,8 @@ import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpression;
|
||||
@@ -29,6 +31,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
public class ZUGFeRDImporter extends ZUGFeRDInvoiceImporter {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ZUGFeRDImporter.class);
|
||||
@@ -472,17 +475,6 @@ public class ZUGFeRDImporter extends ZUGFeRDInvoiceImporter {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return raw XML of the invoice
|
||||
*/
|
||||
public String getMeta() {
|
||||
if (rawXML == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new String(rawXML, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
|
||||
public int getVersion() throws Exception {
|
||||
if (!containsMeta) {
|
||||
@@ -517,20 +509,6 @@ public class ZUGFeRDImporter extends ZUGFeRDInvoiceImporter {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* will return true if the metadata (just extract-ed or set with setMeta) contains ZUGFeRD XML
|
||||
*
|
||||
* @return true if the invoice contains ZUGFeRD XML
|
||||
*/
|
||||
public boolean canParse() {
|
||||
|
||||
// SpecifiedExchangedDocumentContext is in the schema, so a relatively good
|
||||
// indication if zugferd is present - better than just invoice
|
||||
final String meta = getMeta();
|
||||
return (meta != null) && (meta.length() > 0) && ((meta.contains("SpecifiedExchangedDocumentContext")
|
||||
/* ZF1 */ || meta.contains("ExchangedDocumentContext") /* ZF2 */));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns an instance of PostalTradeAddress for SellerTradeParty section
|
||||
|
||||
@@ -311,36 +311,62 @@ public class ZUGFeRDInvoiceImporter {
|
||||
setRawXML(rawXML, true);
|
||||
}
|
||||
|
||||
private void setDocument() throws ParserConfigurationException, IOException, SAXException, ParseException {
|
||||
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
//REDHAT
|
||||
//https://www.blackhat.com/docs/us-15/materials/us-15-Wang-FileCry-The-New-Age-Of-XXE-java-wp.pdf
|
||||
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
||||
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
|
||||
|
||||
//OWASP
|
||||
//https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
|
||||
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||
// Disable external DTDs as well
|
||||
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||
// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
|
||||
dbf.setXIncludeAware(false);
|
||||
dbf.setExpandEntityReferences(false);
|
||||
dbf.setNamespaceAware(true);
|
||||
final DocumentBuilder builder = dbf.newDocumentBuilder();
|
||||
/**
|
||||
* @return raw XML of the invoice
|
||||
*/
|
||||
public String getMeta() {
|
||||
if (rawXML == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new String(rawXML, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* will return true if the metadata (just extract-ed or set with setMeta) contains ZUGFeRD XML
|
||||
*
|
||||
* @return true if the invoice contains ZUGFeRD XML
|
||||
*/
|
||||
public boolean canParse() {
|
||||
|
||||
// SpecifiedExchangedDocumentContext is in the schema, so a relatively good
|
||||
// indication if zugferd is present - better than just invoice
|
||||
final String meta = getMeta();
|
||||
if ((meta == null) || (meta.length() == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ByteArrayInputStream is = new ByteArrayInputStream(rawXML);
|
||||
/// is.skip(guessBOMSize(is));
|
||||
document = builder.parse(is);
|
||||
if (parseAutomatically) {
|
||||
try {
|
||||
importedInvoice = new CalculatedInvoice();
|
||||
extractInto(importedInvoice);
|
||||
} catch (XPathExpressionException e) {
|
||||
throw new RuntimeException(e);
|
||||
try {
|
||||
DocumentBuilder builder = XMLTools.getDocumentBuilder();
|
||||
document = builder.parse(is);
|
||||
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return ((meta.contains("SpecifiedExchangedDocumentContext")
|
||||
/* ZF1 */ || meta.contains("ExchangedDocumentContext") /* ZF2 */));
|
||||
}
|
||||
|
||||
private void setDocument() throws ParserConfigurationException, IOException, SAXException, ParseException {
|
||||
|
||||
|
||||
final ByteArrayInputStream is = new ByteArrayInputStream(rawXML);
|
||||
/// is.skip(guessBOMSize(is));
|
||||
DocumentBuilder builder = XMLTools.getDocumentBuilder();
|
||||
if (canParse()) {
|
||||
document = builder.parse(is);
|
||||
if (parseAutomatically) {
|
||||
try {
|
||||
importedInvoice = new CalculatedInvoice();
|
||||
extractInto(importedInvoice);
|
||||
} catch (XPathExpressionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user