diff --git a/batik-bridge/src/main/java/org/apache/batik/bridge/BridgeContext.java b/batik-bridge/src/main/java/org/apache/batik/bridge/BridgeContext.java index c72484b496..413a1af783 100644 --- a/batik-bridge/src/main/java/org/apache/batik/bridge/BridgeContext.java +++ b/batik-bridge/src/main/java/org/apache/batik/bridge/BridgeContext.java @@ -270,6 +270,28 @@ public class BridgeContext implements ErrorConstants, CSSContext { */ protected float animationLimitingAmount; + protected int useElementBridgeCalculationLimit = DEFAULT_USE_ELEMENT_CALCULATION_BRIDGE_LIMIT; + + public static final int DEFAULT_USE_ELEMENT_CALCULATION_BRIDGE_LIMIT = 1024; + + public int getUseElementBridgeCalculationLimit() { + return useElementBridgeCalculationLimit; + } + + public void setUseElementBridgeCalculationLimit(int useElementBridgeCalculationLimit) { + this.useElementBridgeCalculationLimit = useElementBridgeCalculationLimit; + } + + public boolean stopAfterConsumeUseElementBridgeCalculationLimit() { + int useElementBridgeCalculationLimit = this.getUseElementBridgeCalculationLimit(); + if (useElementBridgeCalculationLimit <= 0) { + return true; + } + --useElementBridgeCalculationLimit; + this.setUseElementBridgeCalculationLimit(useElementBridgeCalculationLimit); + return false; + } + /** * By default we share a unique instance of InterpreterPool. */ diff --git a/batik-bridge/src/main/java/org/apache/batik/bridge/SVGUseElementBridge.java b/batik-bridge/src/main/java/org/apache/batik/bridge/SVGUseElementBridge.java index 2a6593aacb..60f5f5133c 100644 --- a/batik-bridge/src/main/java/org/apache/batik/bridge/SVGUseElementBridge.java +++ b/batik-bridge/src/main/java/org/apache/batik/bridge/SVGUseElementBridge.java @@ -113,6 +113,11 @@ public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) { */ public CompositeGraphicsNode buildCompositeGraphicsNode (BridgeContext ctx, Element e, CompositeGraphicsNode gn) { + + if (ctx.stopAfterConsumeUseElementBridgeCalculationLimit()) { + return null; + } + // get the referenced element SVGOMUseElement ue = (SVGOMUseElement) e; String uri = ue.getHref().getAnimVal(); @@ -159,6 +164,9 @@ public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) { for (Node n = localRefElement.getFirstChild(); n != null; n = localRefElement.getFirstChild()) { + if (ctx.stopAfterConsumeUseElementBridgeCalculationLimit()) { + return null; + } svgElement.appendChild(n); } localRefElement = svgElement; diff --git a/batik-test-old/src/test/java/org/apache/batik/apps/rasterizer/SVGConverterTest.java b/batik-test-old/src/test/java/org/apache/batik/apps/rasterizer/SVGConverterTest.java index 2a83ff05f4..6bff76c0e5 100644 --- a/batik-test-old/src/test/java/org/apache/batik/apps/rasterizer/SVGConverterTest.java +++ b/batik-test-old/src/test/java/org/apache/batik/apps/rasterizer/SVGConverterTest.java @@ -415,6 +415,17 @@ protected void configure(SVGConverter c){ addTest(t); t.setId("OutputTest.reference"); + t = new ConverterOutputTest("samples/manyuse.svg", // File to convert + "test-reports/manyuse.png", // Output + "test-references/samples/manyuse.png"); // reference + addTest(t); + t.setId("manyuse"); + + t = new ConverterOutputTest("samples/3points.svg", // File to convert + "test-reports/3points.png", // Output + "test-references/samples/3points.png"); // reference + addTest(t); + t.setId("3points"); } } diff --git a/samples/3points.svg b/samples/3points.svg new file mode 100644 index 0000000000..124d3e8f8b --- /dev/null +++ b/samples/3points.svg @@ -0,0 +1,5 @@ + + + + +