Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Path.array() cannot read the data if the PathCommands have shortened sign-separated coordinates #1165

Closed
adaliszk opened this issue Oct 29, 2020 · 9 comments

Comments

@adaliszk
Copy link

adaliszk commented Oct 29, 2020

Bug report

Path.array() fails to parse the data into PathCommand correctly when I work with an SVG document that has + signs instead of , signs between the coordinates. There is a workaround to go through all of the places and replace the problematic character, but that is very expensive with large documents and it should not be necessary.

Fiddle

https://jsfiddle.net/vmq83e6z/2/

Explanation

  • What is the behaviour you expect?
    I expect that when accessing an otherwise valid SVG Path Data the Path.array() would able to read the nodes properly

  • What is happening instead?
    It fails to read the coordinates as the divider is not "," but "+". The usage of the divider should be fine as it gets parsed and displayed correctly by the browsers.

  • What error message are you getting?
    There is no error though I wish it were thrown an error when it fails to parse the data correctly.

UPDATE:

Further investigating why is it working within the browser it turns out that this is an intended hidden perk of the data description because the spec defines that coordinates can have signs between them in order to have negative coordinates. They allow to put the positive end there, and they also allow to shorten the path command description by removing the white-space characters which are in this case defined to be command and other characters like #x9 #x20 #xA #xC #xD

So the whole story is that a command's coordinate can be defined as follows:
https://www.w3.org/TR/SVG/paths.html#PathDataBNF

coordinate_pair::= coordinate comma_wsp? coordinate
coordinate::= sign? number

sign::= "+"|"-"
number ::= ([0-9])+
comma_wsp::=(wsp+ ","? wsp*) | ("," wsp*)
wsp ::= (#x9 | #x20 | #xA | #xC | #xD)

and you can remove the wsp and the comma_wsp if there is a command or a sign to separate the attributes (https://www.w3.org/TR/SVG/paths.html#PathDataGeneralInformation)

This whole set then makes it possible to define the path data like any of the lines:

  • M 0,0 L100,0 L200,100 Z
  • M 0,0 L100,0 200,100 Z
  • M 0 0 L 100 0 L 200 100 Z
  • M 0 0 L 100 0 200 100 Z
  • M0+0L100+0L200+100Z
  • M0+0L100+0 200+100Z
  • M0+0L100+0+200+100Z
  • M+0+0L+100+0L+200+100Z
  • M+0+0L+100+0+200+100Z
  • M+0+0 L+100+0 L+200+100 Z
  • M+0+0 L+100+0+200+100 Z
@Fuzzyma
Copy link
Member

Fuzzyma commented Oct 30, 2020

Please show me the part of the spec which allows plus signs in path data because that is completely new to me :D

@BrianHanechak
Copy link

I hadn't seen this before either. It's not that "+" is a divider, it's that it's a sign.. from https://www.w3.org/TR/SVG/paths.html ...

coordinate::= sign? number

sign::= "+"|"-"

So, M+5+5 is just as legal as M5 5 or M5,5. However M+5+-5 would probably not be legal, because I think it would be interpreted as three coordinates, 5, 0, and -5. (This is based on my reading of the paragraph just below the grammar.)

@adaliszk
Copy link
Author

@Fuzzyma, I will have to go deep in the if you really want that, but the fact is that the format works in your main platform the browser and I would assume that the browsers did implement the spec and that kind of way to describe a path is just a hidden perk somewhere in the spec just like @BrianHanechak described.

And yes, the M+5+-5 is not working, it does not even have to be a double sign. I'll update the title because I was wrong about divider, it's actually a sign that allows you to not put a divider character between the coordinates, thanks for the clarification Brian!

@adaliszk adaliszk changed the title Path.array() cannot read the data has "+" instead of "," for coordinates Path.array() cannot read the data if the PathCommands have shortened sign-separated coordinates Oct 30, 2020
@adaliszk
Copy link
Author

adaliszk commented Oct 30, 2020

One thing that caught my eye now that technically the comma separation should be not the default by the spec either but it is working because they define the comma as a whitespace character alongside the space:

https://www.w3.org/TR/SVG/paths.html#PathDataBNF

coordinate_pair::= coordinate comma_wsp? coordinate
coordinate::= sign? number

sign::= "+"|"-"
number ::= ([0-9])+
comma_wsp::=(wsp+ ","? wsp*) | ("," wsp*)
wsp ::= (#x9 | #x20 | #xA | #xC | #xD)

They also specify that you can shorten the data by removing the white spaces if there is a clear separation point between the commands in: https://www.w3.org/TR/SVG/paths.html#PathDataGeneralInformation

@adaliszk
Copy link
Author

@Fuzzyma I've updated the description with the spec related parts, I hope it will clear things out for you in order to fix it.

@Fuzzyma
Copy link
Member

Fuzzyma commented Oct 30, 2020

Thanks for diving into this. Will fix it as soon as I find some time

@Fuzzyma Fuzzyma closed this as completed in 06ac034 Sep 3, 2023
@Fuzzyma
Copy link
Member

Fuzzyma commented Sep 3, 2023

I am incredibly sorry that it took 3 years. Just pushed the fix

@adaliszk
Copy link
Author

adaliszk commented Sep 3, 2023

No need to apologize; I could have opened a PR with it, but since I've moved on from my role where I used the library, I have not done so.

@Fuzzyma
Copy link
Member

Fuzzyma commented Jun 18, 2024

I am sorry - again, I somehow forgot to publish all the fixes I made. I just released it:
https://github.com/svgdotjs/svg.js/releases/tag/3.2.1

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants