diff --git a/src/pugixml.cpp b/src/pugixml.cpp index c314e315f..038097d16 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -8921,6 +8921,21 @@ PUGI_IMPL_NS_BEGIN // parse integer part while (PUGI_IMPL_IS_CHARTYPEX(*string, ctx_digit)) ++string; + // scientific notation no decimal part + if (*string == 'e' || *string == 'E') + { + ++string; + + // parse exponent sign + if (*string == '+' || *string == '-') ++string; + + // there should be at least one digit in exponent + if (!PUGI_IMPL_IS_CHARTYPEX(*string, ctx_digit)) return false; + + // parse exponent digits + while (PUGI_IMPL_IS_CHARTYPEX(*string, ctx_digit)) ++string; + } + // parse decimal part if (*string == '.') { @@ -8929,6 +8944,21 @@ PUGI_IMPL_NS_BEGIN while (PUGI_IMPL_IS_CHARTYPEX(*string, ctx_digit)) ++string; } + // scientific notation with decimal part + if (*string == 'e' || *string == 'E') + { + ++string; + + // parse exponent sign + if (*string == '+' || *string == '-') ++string; + + // there should be at least one digit in exponent + if (!PUGI_IMPL_IS_CHARTYPEX(*string, ctx_digit)) return false; + + // parse exponent digits + while (PUGI_IMPL_IS_CHARTYPEX(*string, ctx_digit)) ++string; + } + // parse trailing whitespace while (PUGI_IMPL_IS_CHARTYPE(*string, ct_space)) ++string; @@ -9821,6 +9851,14 @@ PUGI_IMPL_NS_BEGIN while (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_digit)) cur++; + // Scientific notation support + if (*cur == 'e' || *cur == 'E') + { + cur++; + if (*cur == '+' || *cur == '-') cur++; + while (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_digit)) cur++; + } + _cur_lexeme_contents.end = cur; _cur_lexeme = lex_number; @@ -9886,6 +9924,14 @@ PUGI_IMPL_NS_BEGIN while (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_digit)) cur++; } + // Scientific notation support + if (*cur == 'e' || *cur == 'E') + { + cur++; + if (*cur == '+' || *cur == '-') cur++; + while (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_digit)) cur++; + } + _cur_lexeme_contents.end = cur; _cur_lexeme = lex_number; diff --git a/tests/test_xpath_parse.cpp b/tests/test_xpath_parse.cpp index bfa59ff34..c1e5e38f0 100644 --- a/tests/test_xpath_parse.cpp +++ b/tests/test_xpath_parse.cpp @@ -32,6 +32,13 @@ TEST(xpath_number_parse) CHECK_XPATH_NUMBER(c, STR(".123"), 0.123); CHECK_XPATH_NUMBER(c, STR("123.4567890123456789012345"), 123.4567890123456789012345); CHECK_XPATH_NUMBER(c, STR("123."), 123); + CHECK_XPATH_NUMBER(c, STR("number(-2.5E-2)"), -2.5E-2); + CHECK_XPATH_NUMBER(c, STR("-2.5E-2"), -2.5E-2); + CHECK_XPATH_NUMBER(c, STR("3.0e+5"), 3.0e+5); + CHECK_XPATH_NUMBER(c, STR("3.0e-5"), 3.0e-5); + CHECK_XPATH_NUMBER(c, STR("7.2e0"), 7.2e0); + CHECK_XPATH_NUMBER(c, STR("1e3"), 1e3); + CHECK_XPATH_NUMBER(c, STR("1.e3"), 1e3); } TEST(xpath_number_error) @@ -376,7 +383,7 @@ TEST(xpath_parse_oom_propagation) { std::basic_string literal(i, 'a'); std::basic_string query = STR("processing-instruction('") + literal + STR("') | ") + query_base; - + CHECK_ALLOC_FAIL(CHECK_XPATH_FAIL(query.c_str())); } }