Skip to content

Commit

Permalink
fixes OOM error with multiple decimal points in a number literal (#413)
Browse files Browse the repository at this point in the history
  • Loading branch information
uklimaschewski authored Nov 25, 2023
1 parent 27a9c7b commit c911cf8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/main/java/com/ezylang/evalex/parser/Tokenizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ private boolean implicitMultiplicationPossible(Token currentToken) {
}

private void validateToken(Token currentToken) throws ParseException {

if (currentToken.getType() == STRUCTURE_SEPARATOR && getPreviousToken() == null) {
throw new ParseException(currentToken, "Misplaced structure operator");
}

Token previousToken = getPreviousToken();
if (previousToken != null
&& previousToken.getType() == INFIX_OPERATOR
Expand Down Expand Up @@ -365,7 +370,17 @@ private Token parseDecimalNumberLiteral() throws ParseException {

int lastChar = -1;
boolean scientificNotation = false;
boolean dotEncountered = false;
while (currentChar != -1 && isAtNumberChar()) {
if (currentChar == '.' && dotEncountered) {
tokenValue.append((char) currentChar);
throw new ParseException(
new Token(tokenStartIndex, tokenValue.toString(), TokenType.NUMBER_LITERAL),
"Number contains more than one decimal point");
}
if (currentChar == '.') {
dotEncountered = true;
}
if (currentChar == 'e' || currentChar == 'E') {
scientificNotation = true;
}
Expand Down Expand Up @@ -510,7 +525,7 @@ private boolean isAtNumberChar() {
return Character.isDigit(currentChar) || currentChar == '+' || currentChar == '-';
}

if (previousChar == '.') {
if (previousChar == '.' && currentChar != '.') {
return Character.isDigit(currentChar) || currentChar == 'e' || currentChar == 'E';
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,19 @@ void testScientificLiteralsParseException(String expression) {
.isInstanceOf(ParseException.class)
.hasMessage("Illegal scientific format");
}

@ParameterizedTest
@ValueSource(strings = {"1..0*2.7*195.0", "123.45.6", "2.1.2..4", ".2.4"})
void testMoreThanOneDecimalPointThrowsException(String expression) {
assertThatThrownBy(() -> new Tokenizer(expression, configuration).parse())
.isInstanceOf(ParseException.class)
.hasMessage("Number contains more than one decimal point");
}

@Test
void testMisplacedStructureOperator() {
assertThatThrownBy(() -> new Tokenizer("..3", configuration).parse())
.isInstanceOf(ParseException.class)
.hasMessage("Misplaced structure operator");
}
}

0 comments on commit c911cf8

Please sign in to comment.