From b5d123600a47d927a4903b2ebc28c3304cf0410a Mon Sep 17 00:00:00 2001 From: sb123sb123 <152394158+sb123sb123@users.noreply.github.com> Date: Mon, 21 Sep 2026 23:06:41 +0800 Subject: [PATCH] fix(number): stop float parsing before non-exponent e --- src/number/complete.rs | 8 +++++--- src/number/mod.rs | 11 ++++++++--- src/number/streaming.rs | 8 +++++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/number/complete.rs b/src/number/complete.rs index d8a2a978e..4854f4edf 100644 --- a/src/number/complete.rs +++ b/src/number/complete.rs @@ -3,12 +3,12 @@ use crate::branch::alt; use crate::bytes::complete::tag; use crate::character::complete::{char, digit1, sign}; -use crate::combinator::{cut, map, opt, recognize}; +use crate::combinator::{cut, eof, map, opt, recognize}; use crate::error::ErrorKind; use crate::error::ParseError; use crate::internal::*; use crate::lib::std::ops::{Add, Shl}; -use crate::sequence::pair; +use crate::sequence::{pair, preceded}; use crate::traits::{AsBytes, AsChar, Compare, Input, Offset}; /// Recognizes an unsigned 1 byte integer. @@ -1257,7 +1257,7 @@ where opt(( alt((char('e'), char('E'))), opt(alt((char('+'), char('-')))), - cut(digit1) + alt((digit1, preceded(eof, cut(digit1)))) )) )).parse(input) } @@ -1842,6 +1842,8 @@ mod tests { assert_parse!(double(test), Ok(("", expected64))); } + assert_parse!(recognize_float("123episode"), Ok(("episode", "123"))); + let remaining_exponent = "-1.234E-"; assert_parse!( recognize_float(remaining_exponent), diff --git a/src/number/mod.rs b/src/number/mod.rs index 9e7e3d7e8..276c12be4 100644 --- a/src/number/mod.rs +++ b/src/number/mod.rs @@ -8,9 +8,9 @@ use core::{ use crate::{ branch::alt, character::{char, digit1}, - combinator::{cut, map, opt, recognize}, + combinator::{cut, eof, map, opt, recognize}, error::{make_error, ErrorKind, ParseError}, - sequence::pair, + sequence::{pair, preceded}, AsBytes, AsChar, Compare, Either, Emit, Err, Input, IsStreaming, Mode, Needed, Offset, OutputM, Parser, }; @@ -1317,7 +1317,7 @@ where opt(( alt((char('e'), char('E'))), opt(alt((char('+'), char('-')))), - cut(digit1()) + alt((digit1(), preceded(eof, cut(digit1())))) )) )) } @@ -1464,6 +1464,11 @@ mod tests { assert_parse!(double().parse_complete(test), Ok(("", expected64))); } + assert_parse!( + recognize_float().parse_complete("123episode"), + Ok(("episode", "123")) + ); + let remaining_exponent = "-1.234E-"; assert_parse!( recognize_float().parse_complete(remaining_exponent), diff --git a/src/number/streaming.rs b/src/number/streaming.rs index cd892d657..d45da1e58 100644 --- a/src/number/streaming.rs +++ b/src/number/streaming.rs @@ -3,10 +3,10 @@ use crate::branch::alt; use crate::bytes::streaming::tag; use crate::character::streaming::{char, digit1, sign}; -use crate::combinator::{cut, map, opt, recognize}; +use crate::combinator::{cut, eof, map, opt, recognize}; use crate::error::{ErrorKind, ParseError}; use crate::lib::std::ops::{Add, Shl}; -use crate::sequence::pair; +use crate::sequence::{pair, preceded}; use crate::traits::{AsBytes, AsChar, Compare, Offset}; use crate::{internal::*, Input}; @@ -1224,7 +1224,7 @@ where opt(( alt((char('e'), char('E'))), opt(alt((char('+'), char('-')))), - cut(digit1) + alt((digit1, preceded(eof, cut(digit1)))) )) )).parse(input) } @@ -1937,6 +1937,8 @@ mod tests { assert_parse!(double(&larger[..]), Ok((";", expected64))); } + assert_parse!(recognize_float("123episode"), Ok(("episode", "123"))); + let remaining_exponent = "-1.234E-"; assert_parse!( recognize_float(remaining_exponent),