SVG loading crashes when "points" value starts with a negative symbol
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
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