geomerative icon indicating copy to clipboard operation
geomerative copied to clipboard

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

Open euphy opened this issue 6 years ago • 1 comments

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

euphy avatar Mar 12 '19 23:03 euphy

Hi,

Indeed, it is a bug.

Please do send in a pull request if it is not too much trouble.

cheers

On Wed, Mar 13, 2019 at 12:34 AM Sandy Noble [email protected] wrote:

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

<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">

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.(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

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/rikrd/geomerative/issues/9, or mute the thread https://github.com/notifications/unsubscribe-auth/AAA73CTminw4EN3cUncLHBM-QxdFxkATks5vWDlygaJpZM4bsFpz .

-- ricard http://twitter.com/ricardmp http://www.ricardmarxer.com http://www.caligraft.com

rikrd avatar Mar 13 '19 19:03 rikrd