-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Odd number parsing #10
Comments
Fascinating! Your analysis seems to be correct. It looks to me like Crass is actually parsing this CSS correctly according to the spec, which results in In this case the value of the number token shouldn't really matter since it ultimately won't be used as a number. But Crass doesn't impose an upper bound on numbers, and this is a ridiculously large one, which is what's causing the problem. Seems like the right thing to do here would probably be to clamp number values to a maximum value, but I (or someone) will need to do some research to see what, if anything, the available standards say about this in order to figure out what that number should be. |
Attempting to represent this in ruby:
Note that An exponent can be either a very large number or a very small number, so it's normally represented as a float (which does have limits). However, in this exact case, the giant number (5×10^1367490) is being handled as a Bignum internally and I can't find any reference to limits there except those imposed by system resources. Suggestions for limits Since Ruby would normally represent an exponent as a Float, we could use the MAX/MIN values provided by ruby-core / Float:
Suggestion to convert to float Currently, Crass represents 5e100000 as an Integer and 5e-100000 as a Rational. If exponents are typically represents as floats, the principle of least surprise would suggest that they should probably be parsed into a ruby Float in the first place... It also appears to be the more memory efficient option:
|
@veesahni Thanks for that excellent summary. I agree that using a Float sounds like the best option. I may have time to work on this this weekend, but if you need this fixed sooner a PR would be welcome! |
Number values are now limited to a maximum of `Float::MAX` and a minimum of negative `Float::MAX`. Internally, `Integer` is now used for numbers parsed as the "integer" type (as defined in the spec), while `Float` is used for numbers parsed as the "number" type. Fixes #10
In real world samples, we give Crass hundreds/thousands such exponent looking names in a single call to parse. The giant numbers were causing RSS (resident set size) to balloon. Sending similar samples through the new code keeps RSS in check - so yes, this solves the problem! Appreciate the quick turn around :) |
Environment:
MRI Ruby 2.6.5
Crass 1.05
Real excerpt from an email sent by Outlook:
Test code:
Output:
Can't paste on github since output is > 65KB. There are some giant numbers that result from attempting to convert "5e1367490fa5f06927cafe55msonormal" into a number.
Analysis:
It appears that Crass is trying to parse these names (class name, style name) into a number. This is ending up in a giant number that results in large amounts of memory usage in the generated parse tree. Is this a bug?
The text was updated successfully, but these errors were encountered: