Skip to content

SVG loading crashes when "points" value starts with a negative symbol #9

@euphy

Description

@euphy

Love this library, and have dug out a small problem with an SVG that looks like this:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.0" id="Lager_1" xmlns:slic3r="http://slic3r.org/namespaces/slic3r" xmlns:svg="http://www.w3.org/2000/svg"
	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 611.9 586.3"
	 style="enable-background:new 0 0 611.9 586.3;" xml:space="preserve">
<style type="text/css">
	.st0{fill:#FFFFFF;}
</style>
<g>

	<polygon slic3r:type="contour" class="st0" points="-1.8,579 -1.8,579.1 -1.8,579.8 -1.8,580 -1.8,580 -1.8,580 -1.9,580 -2,580 
		-2,579.4 -2,579.1 -1.9,579 	">
	</polygon>
</g>
</svg>

The value of points in the only polygon starts with a negative number (-1.8,579) and this is caught by a branch in the part of RSVG.getPolyline() that checks for scientific notation (I think!).

        switch(charline[i])
          {
          case '-':
            if(charline[i-1] != 'e' && charline[i-1] != 'E'){
              charline=PApplet.splice(charline,' ',i);
              i++;
            }
break;

(https://github.com/rikrd/geomerative/blob/master/src/geomerative/RSVG.java#L744)

In this case, when the first char is '-', then i-1 triggers an ArrayIndexOutOfBoundsException. It looks like this in my application:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
	at geomerative.RSVG.getPolyline(Unknown Source)
	at geomerative.RSVG.elemToPolyline(Unknown Source)
	at geomerative.RSVG.elemToPolygon(Unknown Source)
	at geomerative.RSVG.elemToCompositeShape(Unknown Source)
	at geomerative.RSVG.elemToCompositeShape(Unknown Source)
	at geomerative.RSVG.toShape(Unknown Source)
	at geomerative.RG.loadShape(Unknown Source)
	at polargraphcontroller.loadShapeFromFile(polargraphcontroller.java:4574)
	at polargraphcontroller$9.run(polargraphcontroller.java:4453)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$200(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

My calling code is here: https://github.com/euphy/polargraphcontroller/blob/master/polargraphcontroller.pde#L2744

I've tried to replicate this error with your own examples in geomerative, but I'm getting a different error entirely:

with_negative_first_coord.svg does not exist or could not be read
java.lang.NullPointerException
	at processing.data.XML$1.read(XML.java:190)
	at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.arrangeCapacity(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipString(Unknown Source)
	at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
	at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
	at processing.data.XML.<init>(XML.java:187)
	at processing.core.PApplet.loadXML(PApplet.java:6322)
	at processing.core.PApplet.loadXML(PApplet.java:6312)
	at geomerative.RSVG.toShape(Unknown Source)
	at geomerative.RG.loadShape(Unknown Source)
	at Tutorial_16_HelloSVGtoPDF.setup(Tutorial_16_HelloSVGtoPDF.java:31)
	at processing.core.PApplet.handleDraw(PApplet.java:2361)
	at processing.core.PGraphicsJava2D.requestDraw(PGraphicsJava2D.java:240)
	at processing.core.PApplet.run(PApplet.java:2256)
	at java.lang.Thread.run(Unknown Source)

I don't see the difference between the two situations, but I can dig further if it's helpful.

I have solved this problem by changing https://github.com/rikrd/geomerative/blob/master/src/geomerative/RSVG.java#L744 to be

            if(i>0 && charline[i-1] != 'e' && charline[i-1] != 'E'){

That's adding an extra clause into the if condition: if it's greater than 0, then it's safe to look backwards for the E.

I can make a pull request for this if you'd like.

Thanks for making such a brill library!

sn

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions