CSSTree: fix uncaught exceptions when parsing hexadecimal color values and number values by adding problems when invalid
diff --git a/compiler/src/main/antlr3/org/apache/royale/compiler/internal/css/CSSTree.g b/compiler/src/main/antlr3/org/apache/royale/compiler/internal/css/CSSTree.g
index 138f3f0..b027a44 100644
--- a/compiler/src/main/antlr3/org/apache/royale/compiler/internal/css/CSSTree.g
+++ b/compiler/src/main/antlr3/org/apache/royale/compiler/internal/css/CSSTree.g
@@ -639,11 +639,23 @@
singleValue returns [CSSPropertyValue propertyValue]
: NUMBER_WITH_PERCENT
- { $propertyValue = new CSSNumberPropertyValue($NUMBER_WITH_PERCENT.text, $start, tokenStream); }
+ {
+ CSSNumberPropertyValue numWithPercentValue = new CSSNumberPropertyValue($NUMBER_WITH_PERCENT.text, $start, tokenStream);
+ problems.addAll(numWithPercentValue.getProblems());
+ $propertyValue = numWithPercentValue;
+ }
| NUMBER_WITH_UNIT
- { $propertyValue = new CSSNumberPropertyValue($NUMBER_WITH_UNIT.text, $start, tokenStream); }
+ {
+ CSSNumberPropertyValue numWithUnitValue = new CSSNumberPropertyValue($NUMBER_WITH_UNIT.text, $start, tokenStream);
+ problems.addAll(numWithUnitValue.getProblems());
+ $propertyValue = numWithUnitValue;
+ }
| HASH_WORD
- { $propertyValue = new CSSColorPropertyValue($start, tokenStream); }
+ {
+ CSSColorPropertyValue colorValue = new CSSColorPropertyValue($start, tokenStream);
+ problems.addAll(colorValue.getProblems());
+ $propertyValue = colorValue;
+ }
| ALPHA_VALUE
{
if (strictFlexCSS)
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSColorPropertyValue.java b/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSColorPropertyValue.java
index 534266f..9c6b231 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSColorPropertyValue.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSColorPropertyValue.java
@@ -19,9 +19,16 @@
package org.apache.royale.compiler.internal.css;
+import java.util.ArrayList;
+import java.util.List;
+
import org.antlr.runtime.Token;
import org.antlr.runtime.TokenStream;
import org.antlr.runtime.tree.CommonTree;
+import org.apache.royale.compiler.common.ISourceLocation;
+import org.apache.royale.compiler.common.SourceLocation;
+import org.apache.royale.compiler.problems.CSSInvalidRGBProblem;
+import org.apache.royale.compiler.problems.ICompilerProblem;
import com.google.common.collect.ImmutableMap;
@@ -213,7 +220,17 @@
six.append(tokenText.charAt(3));
tokenText = six.toString();
}
- this.colorInt = Integer.parseInt(tokenText.substring(1), 16);
+ int parsedColorInt = 0;
+ try
+ {
+ parsedColorInt = Integer.parseInt(tokenText.substring(1), 16);
+ }
+ catch (NumberFormatException e)
+ {
+ ISourceLocation sourceLocation = new SourceLocation(tokenStream.getSourceName(), UNKNOWN, UNKNOWN, tree.getLine(), tree.getCharPositionInLine());
+ problems.add(new CSSInvalidRGBProblem(sourceLocation, tokenText));
+ }
+ this.colorInt = parsedColorInt;
}
/**
@@ -236,6 +253,13 @@
private final Token token;
private final int colorInt;
+ private final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>();
+
+ public List<ICompilerProblem> getProblems()
+ {
+ return problems;
+ }
+
/**
* @return Integer value for the 24-bit color.
*/
diff --git a/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSNumberPropertyValue.java b/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSNumberPropertyValue.java
index d2bd7f9..7be9ae0 100644
--- a/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSNumberPropertyValue.java
+++ b/compiler/src/main/java/org/apache/royale/compiler/internal/css/CSSNumberPropertyValue.java
@@ -19,11 +19,17 @@
package org.apache.royale.compiler.internal.css;
+import java.util.ArrayList;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.antlr.runtime.TokenStream;
import org.antlr.runtime.tree.CommonTree;
+import org.apache.royale.compiler.common.ISourceLocation;
+import org.apache.royale.compiler.common.SourceLocation;
+import org.apache.royale.compiler.problems.CSSInvalidNumberProblem;
+import org.apache.royale.compiler.problems.ICompilerProblem;
/**
* Implementation for number CSS property values. The number can also have a
@@ -52,16 +58,33 @@
assert numberWithUnit != null : "Number can't be null.";
final Matcher matcher = PATTERN.matcher(numberWithUnit);
+ String numberWithoutUnit = null;
if (matcher.find())
{
- this.number = Float.parseFloat(matcher.group());
- this.unit = numberWithUnit.substring(matcher.end());
+ numberWithoutUnit = matcher.group();
+ float parsedFloat = Float.parseFloat(numberWithoutUnit);
+ if (Float.isInfinite(parsedFloat) || Float.isNaN(parsedFloat))
+ {
+ this.number = null;
+ this.unit = null;
+ }
+ else
+ {
+ this.number = parsedFloat;
+ this.unit = numberWithUnit.substring(matcher.end());
+ }
}
else
{
+ numberWithoutUnit = "";
this.number = null;
this.unit = null;
}
+ if (this.number == null)
+ {
+ ISourceLocation sourceLocation = new SourceLocation(tokenStream.getSourceName(), UNKNOWN, UNKNOWN, tree.getLine(), tree.getCharPositionInLine());
+ problems.add(new CSSInvalidNumberProblem(sourceLocation, numberWithoutUnit));
+ }
this.raw = numberWithUnit;
}
@@ -69,6 +92,13 @@
private final Number number;
private final String unit;
+ private final List<ICompilerProblem> problems = new ArrayList<ICompilerProblem>();
+
+ public List<ICompilerProblem> getProblems()
+ {
+ return problems;
+ }
+
/**
* @return The number value.
*/
diff --git a/compiler/src/main/java/org/apache/royale/compiler/problems/CSSInvalidNumberProblem.java b/compiler/src/main/java/org/apache/royale/compiler/problems/CSSInvalidNumberProblem.java
new file mode 100644
index 0000000..bb48e76
--- /dev/null
+++ b/compiler/src/main/java/org/apache/royale/compiler/problems/CSSInvalidNumberProblem.java
@@ -0,0 +1,40 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ package org.apache.royale.compiler.problems;
+
+import org.apache.royale.compiler.common.ISourceLocation;
+
+/**
+ * Problem generated when a CSS number is invalid.
+ */
+public final class CSSInvalidNumberProblem extends CSSProblem
+{
+ public static final String DESCRIPTION =
+ "Invalid string for number: '${numberText}'";
+
+ public CSSInvalidNumberProblem(ISourceLocation location, String numberText)
+ {
+ super(location);
+ this.numberText = numberText;
+ }
+
+ public final String numberText;
+}
+
\ No newline at end of file
diff --git a/compiler/src/main/java/org/apache/royale/compiler/problems/CSSInvalidRGBProblem.java b/compiler/src/main/java/org/apache/royale/compiler/problems/CSSInvalidRGBProblem.java
new file mode 100644
index 0000000..11ae9d2
--- /dev/null
+++ b/compiler/src/main/java/org/apache/royale/compiler/problems/CSSInvalidRGBProblem.java
@@ -0,0 +1,40 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ package org.apache.royale.compiler.problems;
+
+import org.apache.royale.compiler.common.ISourceLocation;
+
+/**
+ * Problem generated when a CSS hexadecimal RGB color is invalid.
+ */
+public final class CSSInvalidRGBProblem extends CSSProblem
+{
+ public static final String DESCRIPTION =
+ "Invalid RGB color: '${colorText}'";
+
+ public CSSInvalidRGBProblem(ISourceLocation location, String colorText)
+ {
+ super(location);
+ this.colorText = colorText;
+ }
+
+ public final String colorText;
+}
+
\ No newline at end of file
diff --git a/compiler/src/test/java/org/apache/royale/compiler/internal/css/CSSColorPropertyValueTests.java b/compiler/src/test/java/org/apache/royale/compiler/internal/css/CSSColorPropertyValueTests.java
index e6213cb..cd0ca85 100644
--- a/compiler/src/test/java/org/apache/royale/compiler/internal/css/CSSColorPropertyValueTests.java
+++ b/compiler/src/test/java/org/apache/royale/compiler/internal/css/CSSColorPropertyValueTests.java
@@ -115,16 +115,20 @@
}
- // not sure you can expect exception since compiler catches everything
- @Test(expected = NumberFormatException.class)
+ @Test
public void CSSColorPropertyValue_wrong_hexColor2()
{
String code = " color: #FF00FG; ";
- errorFilters = new String[1];
- errorFilters[0] = "Unexpected exception 'java.lang.NumberFormatException";
List<CSSColorPropertyValue> colorProperties = getCSSColorPropertyValues(code);
- assertThat("colorProperties.size()" , colorProperties.size(), is(0) );
+ assertThat("colorProperties.size()" , colorProperties.size(), is(1) );
+
+ CSSColorPropertyValue colorPropertyValue = colorProperties.get(0);
+ assertThat("colorPropertyValue.getOperator()" , colorPropertyValue.getOperator(), is( CSSModelTreeType.PROPERTY_VALUE ) );
+ assertThat("colorPropertyValue.getText()" , colorPropertyValue.getText(), is( "#FF00FG" ) );
+ assertThat("colorPropertyValue.getColorAsInt()" , colorPropertyValue.getColorAsInt(), is( 0 ) );
+
+ assertThat("colorPropertyValue.getProblems().size()" , colorPropertyValue.getProblems().size(), is( 1 ) );
}
}
diff --git a/compiler/src/test/java/org/apache/royale/compiler/internal/css/CSSNumberPropertyValueTests.java b/compiler/src/test/java/org/apache/royale/compiler/internal/css/CSSNumberPropertyValueTests.java
index 9c08b93..cd0c2f9 100644
--- a/compiler/src/test/java/org/apache/royale/compiler/internal/css/CSSNumberPropertyValueTests.java
+++ b/compiler/src/test/java/org/apache/royale/compiler/internal/css/CSSNumberPropertyValueTests.java
@@ -171,5 +171,37 @@
assertThat("numberPropertyValue.getNumber()" , numberPropertyValue.getNumber(), is( (Number) Float.valueOf(-10.31f) ) );
}
+ @Test
+ public void CSSNumberPropertyValue_positiveInfinity_problem()
+ {
+ String code = " fontSize: 123456789876543210123456789876543210123456789px; ";
+
+ List<CSSNumberPropertyValue> numberProperties = getCSSNumberPropertyValues(code);
+ assertThat("numberProperties.size()" , numberProperties.size(), is(1) );
+
+ CSSNumberPropertyValue numberPropertyValue = numberProperties.get(0);
+ assertThat("numberPropertyValue.getOperator()" , numberPropertyValue.getOperator(), is( CSSModelTreeType.PROPERTY_VALUE ) );
+ assertThat("numberPropertyValue.getUnit()" , numberPropertyValue.getUnit(), is( (String) null ) );
+ assertThat("numberPropertyValue.getNumber()" , numberPropertyValue.getNumber(), is( (Number) null ) );
+
+ assertThat("numberPropertyValue.getProblems().size()" , numberPropertyValue.getProblems().size(), is( 1 ) );
+ }
+
+ @Test
+ public void CSSNumberPropertyValue_negativeInfinity_problem()
+ {
+ String code = " fontSize: -123456789876543210123456789876543210123456789px; ";
+
+ List<CSSNumberPropertyValue> numberProperties = getCSSNumberPropertyValues(code);
+ assertThat("numberProperties.size()" , numberProperties.size(), is(1) );
+
+ CSSNumberPropertyValue numberPropertyValue = numberProperties.get(0);
+ assertThat("numberPropertyValue.getOperator()" , numberPropertyValue.getOperator(), is( CSSModelTreeType.PROPERTY_VALUE ) );
+ assertThat("numberPropertyValue.getUnit()" , numberPropertyValue.getUnit(), is( (String) null ) );
+ assertThat("numberPropertyValue.getNumber()" , numberPropertyValue.getNumber(), is( (Number) null ) );
+
+ assertThat("numberPropertyValue.getProblems().size()" , numberPropertyValue.getProblems().size(), is( 1 ) );
+ }
+
}